加入收藏 | 设为首页 | 会员中心 | 我要投稿 拼字网 - 核心网 (https://www.hexinwang.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 编程要点 > 语言 > 正文

分析内存管 理机制的变更,你需要了解

发布时间:2022-12-09 11:17:24 所属栏目:语言 来源:
导读:  这时候可能至少分两拨小伙伴,分别是:

  知道是什么,被这个问题 “折磨“ 过的,瞬间眼前一亮。

  不知道是什么,出现了各种疑惑了,这说的都是些什么。

  灵魂拷问

  你

  这时候可能至少分两拨小伙伴,分别是:
 
  知道是什么,被这个问题 “折磨“ 过的,瞬间眼前一亮。
 
  不知道是什么,出现了各种疑惑了,这说的都是些什么。
 
  灵魂拷问
 
  你有没有以下的疑问,或者是否清楚:
 
  文中所说的 MADV_FREE 是什么?
 
  文中所说的 MADV_DONTNEED 是什么?
 
  为什么特指 Go 语言的 Linux 环境?
 
  为什么是说从 MADV_FREE改回 MADV_DONTNEED?
 
  在今天这篇文章中我们都将进一步的展开和说明,让我们一同来了解这个改来改去的内存机制到底是何物。
 
  madvise 爱与恨
 
  在 Linux 系统中,在 Go Runtime 中通过系统调用 madvise(addr, length, advise) 方法,能够告诉内核如何处理从 addr 开始的 length 字节。
 
  重点之一就是 ”如何处理“,在 Linux 下 Go 语言中目前支持两种策略,分别是(via @felix021):
 
  MADV_FREE:内核会在进程的页表中将这些页标记为 “未分配”,从而进程的 RSS 就会变小。OS 后续可以将对应的物理页分配给其他进程。
 
  MADV_DONTNEED:内核只会在页表中将这些进程页面标记为可回收,在需要的时候才回收这些页面。
 
  所带来的影响
 
  Go 语言官方恰好就在 2019 年的 Go1.12 做了如下调整。
 
  Go1.12 以前。
 
  Go.12-Go1.15.
 
  Go1.12 以前
 
  Go Runtime 在 Linux 上默认使用的是 MADV_DONTNEED 策略。
 
  // 没有任何奇奇怪怪的判断
 
  madvise(v, n, _MADV_DONTNEED)
 
  从整体效果来看,进程 RSS 可以下降的比较快,但从性能效率上来看差点。
 
  Go1.12-Go1.15
 
  当前 Linux 内核版本 >=4.5 时,Go Runtime 在 Linux 上默认使用了性能更为高效的 MADV_FREE 策略。
 
  var advise uint32
 
  if debug.madvdontneed != 0 {
 
   advise = _MADV_DONTNEED
 
  } else {
 
   advise = atomic.Load(&adviseUnused)
 
  }
 
  if errno := madvise(v, n, int32(advise)); advise == _MADV_FREE && errno != 0 {
 
   // MADV_FREE was added in Linux 4.5. Fall back to MADV_DONTNEED if it is
 
   // not supported.
 
   atomic.Store(&adviseUnused, _MADV_DONTNEED)
 
   madvise(v, n, _MADV_DONTNEED)
 
  }
 
  从整体效果来看,进程RSS 不会立刻下降,要等到系统有内存压力了才会释放占用,RSS 才会下降。
 

(编辑:拼字网 - 核心网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!