Go进程的HeapReleased上升,但是RSS不下降造成内存泄漏?

事情是这样的,线上一个服务,启动后RSS随任务数增加而持续上升,但是过了业务高峰期后,任务数已经下降,RSS却没有下降,而是维持在高位水平。

那内存到底被谁持有了呢?为了定位问题,我把进程的各项Go runtime内存指标,以及进程的RSS等指标持续采集下来,并以时间维度绘制成了折线图:

内存折线图

本着DRY原则,我把采集和绘制部分专门制作成了一个开源库,业务方代码可以十分方便的接入,绘制出如上样式的折线图,并通过网页实时查看。git地址:https://github.com/q191201771/pprofplus

图中的指标,VMS和RSS是任何linux进程都有的。Sys、HeapSys、HeapAlloc、HeapInuse、HeapReleased、HeapIdle是Go runtime记录的内存情况。

简单来说,RSS可以认为是进程实际占用内存的大小,也是一个进程外在表现最重要的内存指标。HeapReleased是Go进程归还给操作系统的内存。在 《如何分析golang程序的内存使用情况》 这篇老文章中,实验了随着垃圾回收,HeapReleased上升,RSS下降的过程。

但是这次的案例,从图中可以看到,HeapReleased上升,RSS却从来没有下降过。。

我们来具体分析。(以下我就不重复解释各指标的含义了,对照着看上面那两篇文章就好)

首先从业务的任务数来说,从启动时间03-13 17:47:17开始,是持续增长的,到22:17:17之后开始下降,再到03-14 16:17:27之后,又开始上升。之后就是循环反复。这是业务上实际内存需求的特点。

  • VMS和RSS的整体波形一致,维持在一定差值,符合预期。
  • Sys和RSS几乎重叠,说明确实是Go代码使用的内存,符合预期。
  • HeapSys和Sys的波形一致,维持在一个比较小的差值,说明大部分内存都是堆内存,符合预期。
  • HeapInuse和HeapAlloc是持续震荡的,波形一致,维持在一定差值,业务高峰期时上升,低峰期下降,符合预期。
  • HeapIdle在首次高峰前震荡上升,之后一直和HeapInuse的波形相反,说明起到了缓存的作用,符合预期。
  • HeapIdle和HeapReleased波形一致,符合预期。

那么回到最初的问题,为什么HeapReleased上升,RSS没有下降呢?

这是因为Go底层用mmap申请的内存,会用madvise释放内存。具体见go/src/runtime/mem_linux.go的代码。

madvise将某段内存标记为不再使用时,有两种方式MADV_DONTNEEDMADV_FREE(通过标志参数传入):

  • MADV_DONTNEED标记过的内存如果再次使用,会触发缺页中断
  • MADV_FREE标记过的内存,内核会等到内存紧张时才会释放。在释放之前,这块内存依然可以复用。这个特性从linux 4.5版本内核开始支持

显然,MADV_FREE是一种用空间换时间的优化。

  • Go 1.12之前,linux平台下Go runtime中的sysUnsed使用madvise(MADV_DONTNEED)
  • Go 1.12之后,在MADV_FREE可用时会优先使用MADV_FREE

具体见 https://github.com/golang/go/issues/23687

Go 1.12之后,提供了一种方式强制回退使用MADV_DONTNEED的方式,在执行程序前添加GODEBUG=madvdontneed=1。具体见 https://github.com/golang/go/issues/28466

ok,知道了RSS不释放的原因,回到我们自己的问题上,做个总结。

事实上,我们案例中,进程对执行环境的资源是独占的,也就是说机器只有这一个核心业务进程,内存主要就是给它用的。

所以我们知道了不是自己写的上层业务错误持有了内存,而是底层做的优化,我们开心的用就好。

另一方面,我们应该通过HeapInuse等指标的震荡情况,以及GC的耗时,来观察上层业务是否申请、释放堆内存太频繁了,是否有必要对上层业务做优化,比如减少堆内存,添加内存池等。

好,这篇先写到这,最近还有两个线上实际业务的内存案例,也用到了上面的pprofplus画图分析,有空再写文章分享。

本文完,作者yoko,尊重劳动人民成果,转载请注明原文出处: https://pengrl.com/p/20033/

本篇文章由一文多发平台ArtiPub自动发布

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,117评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,328评论 1 293
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,839评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,007评论 0 206
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,384评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,629评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,880评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,593评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,313评论 1 243
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,575评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,066评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,392评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,052评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,082评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,844评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,662评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,575评论 2 270