成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

詳解內存管理機制的變更,你需要了解

開發 后端
在 Linux 系統中,在 Go Runtime 中通過系統調用 madvise(addr, length, advise) 方法,能夠告訴內核如何處理從 addr 開始的 length 字節。

 [[381172]]

本文轉載自微信公眾號「腦子進煎魚了」,作者陳煎魚。轉載本文請聯系腦子進煎魚了公眾號。

大家好,我是正在學習如何蒸魚的煎魚。

在上一篇 Go1.16 特性介紹的文章中我們有提到,從 v1.16 起,Go 在 Linux 下的默認內存管理策略會從MADV_FREE 改回 MADV_DONTNEED 策略。

這時候可能至少分兩撥小伙伴,分別是:

  • 知道是什么,被這個問題 “折磨“ 過的,瞬間眼前一亮。
  • 不知道是什么,出現了各種疑惑了,這說的都是些什么。

靈魂拷問

你有沒有以下的疑問,或者是否清楚:

  • 文中所說的 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 策略。

  1. // 沒有任何奇奇怪怪的判斷 
  2. madvise(v, n, _MADV_DONTNEED) 

從整體效果來看,進程 RSS 可以下降的比較快,但從性能效率上來看差點。

Go1.12-Go1.15

當前 Linux 內核版本 >=4.5 時,Go Runtime 在 Linux 上默認使用了性能更為高效的 MADV_FREE 策略。

  1. var advise uint32 
  2. if debug.madvdontneed != 0 { 
  3.  advise = _MADV_DONTNEED 
  4. else { 
  5.  advise = atomic.Load(&adviseUnused) 
  6. if errno := madvise(v, n, int32(advise)); advise == _MADV_FREE && errno != 0 { 
  7.  // MADV_FREE was added in Linux 4.5. Fall back to MADV_DONTNEED if it is 
  8.  // not supported. 
  9.  atomic.Store(&adviseUnused, _MADV_DONTNEED) 
  10.  madvise(v, n, _MADV_DONTNEED) 

從整體效果來看,進程RSS 不會立刻下降,要等到系統有內存壓力了才會釋放占用,RSS 才會下降。

帶來的副作用

故事往往不是那么的美好,顯然在 Go1.12 起針對 madvise 的 MADV_FREE 策略的調整非常 “片面”。

來自社區微信群的小伙伴

結合社區里所遇到的案例可得知,該次調整帶來了許多問題:

  • 引發用戶體驗的問題:Go issues 上總是出現以為內存泄露,但其實只是未滿足條件,內存沒有馬上釋放的案例。
  • 混淆統計信息和監控工具的情況:在 Grafana 等監控上,發現容器進程內存較高,釋放很慢,告警了,很慌。
  • 導致與內存使用有關聯的個別管理系統集成不良:例如 Kubernetes HPA ,或者自定義了擴縮容策略這類模式,難以評估。
  • 擠壓同主機上的其他應用資源:并不是所有的 Go 程序都一定獨立跑在單一主機中,自然就會導致同一臺主機上的其他應用受到擠壓,這是難以評估的。

從社區反饋來看是問題多多,弊大于利。

官方本想著想著性能更好一些,但是在現實場景中引發了不少的新問題,甚至有提到和 Android 流程管理不兼容的情況。

有種 “撿了芝麻,丟了西瓜” 的感覺。

Go1.16:峰回路轉

既然社區反饋的問題何其多,有沒有人提呢?有,超級多。

多到提出修改回 MADV_DONTNEED 的 issues 僅花了 1-2 天的時間就討論完畢。

很快得出結論且合并 CL 關閉 issues 了。

Go1.16 修改內容如下:

  1. func parsedebugvars() { 
  2.  // defaults 
  3.  debug.cgocheck = 1 
  4.  debug.invalidptr = 1 
  5.  if GOOS == "linux" { 
  6.   debug.madvdontneed = 1 
  7.  } 
  8.   ... 

直接指定回了 debug.madvdontneed = 1,簡單粗暴。

總結

在本篇文章中,我們針對 Go 語言在 Linux 下的 madvise 方法的策略調整進行了歷史介紹和說明,同時針對其調整所帶來的的副作用及應對措施進行了一一介紹。

本次變更很好的印證了,牽一發動全身的說法。大家在后續應用這塊時也要多加注意。

你覺得 Go1.16 這個特性變更怎么樣呢?歡迎在評論區留言。

參考

runtime: default to MADV_DONTNEED on Linux

踩坑記:go 服務內存暴漲

Go 1.12 關于內存釋放的一個改進

 

責任編輯:武曉燕 來源: 腦子進煎魚了
相關推薦

2010-12-10 15:40:58

JVM內存管理

2010-09-26 13:23:13

JVM內存管理機制

2011-06-29 17:20:20

Qt 內存 QOBJECT

2020-08-18 19:15:44

Redis內存管理

2012-06-26 10:13:55

2011-04-01 11:16:06

hessian

2009-09-02 09:23:26

.NET內存管理機制

2012-06-27 09:11:47

2013-09-29 15:11:46

Linux運維內存管理

2010-07-23 09:34:48

Python

2022-06-01 16:01:58

MySQL內存管理系統

2009-07-08 15:10:00

Servlet會話管理

2015-09-17 09:36:46

Chrome改變

2013-05-15 09:39:14

虛擬化網絡思科虛擬交換機

2020-11-08 14:32:01

JavaScript變量內存管理

2022-02-28 10:25:17

Python參數傳遞拷貝

2016-10-09 14:41:40

Swift開發ARC

2022-01-04 19:28:05

VMware云端虛擬化

2020-10-13 06:56:19

JavaScript異常類型開發

2013-05-15 14:33:43

虛擬化管理虛擬化
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 婷婷国产一区二区三区 | 天天综合日日夜夜 | 国产一区91精品张津瑜 | 成年人在线 | 亚洲精品欧洲 | 91精品国模一区二区三区 | 国产一级电影在线观看 | 一级黄色片日本 | 欧美日韩免费一区二区三区 | 中文在线一区二区 | 欧美日韩在线综合 | 日韩中文欧美 | 国产伦一区二区三区四区 | 欧美日韩电影免费观看 | 欧美久久精品一级c片 | 亚洲精品久久久久久久久久久久久 | 中文字幕在线欧美 | 久久99网| 久久午夜精品 | 一区二区三区精品视频 | 日韩久久久久久 | 亚洲精品视频久久 | 一区二区三区不卡视频 | 在线观看国产wwwa级羞羞视频 | 麻豆一区一区三区四区 | 中文字幕四虎 | 天天插天天干 | 免费一级片 | 天天操夜夜爽 | 中文字幕二区 | 免费视频一区二区 | 国产精品视频一 | 国产一区二区三区精品久久久 | 国产农村妇女精品一二区 | 91久久久久久久久久久久久 | 午夜精品一区二区三区三上悠亚 | 日本高清视频在线播放 | 国产精品久久久久久久久久免费看 | 日操操夜操操 | 精品免费 | 亚洲 欧美 日韩在线 |