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

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

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

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

  • VMS 和 RSS 的含义可以看这篇: 《[译] linux 内存管理之 RSS 和 VSZ 的区别》
  • Go runtime 中的指标含义可以看这篇: 《Go pprof 内存指标含义备忘录》

简单来说,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画图分析,有空再写文章分享。

微信公众号:非常程序员
首发链接:https://pengrl.com/p/20033/

神经网络 误差下降 准确率不上升_Go进程的HeapReleased上升,但是RSS不下降造成内存泄漏?...相关推荐

  1. 神经网络的分类准确率是连续的吗?

    设一个测试集有n张图片,则这个网络的分类准确率只能是(n-x)/n,而n和x只能是整数,因此这个网络的分类准确率只能是一个有理分数,不可能是一个连续值. 神经网络的衰变假设:被概率密度表达的粒子A和B ...

  2. 神经网络的分类准确率到底是一个什么物理量

    r1 r2     <1 <1 吸引子 c >1 >1 排斥子 p >1 <1 鞍点 a <1 >1 反鞍点 fa 用p,a做训练集,用来分类c 可能有 ...

  3. C++内存和进程,线程学习补充(内存泄漏,信号量)

    作为测试人员角度研究了很多内存相关的东西,当我在51发了博客后,通过反馈,针对我的2篇博客在这里进行补充. CPU,进程: http://www.51testing.com/?viewspace-83 ...

  4. linux内存泄漏进程挂掉,Linux 系统内存泄漏的堆积隐患的排查与解决

    [赛迪网报道]Linux系统下真正有危害的是内存泄漏的堆积,这会最终消耗尽系统任何的内存.下面是排查和解决方案与大家一起分享. 1.Linux 内存监控内存泄漏的定义: 一般我们常说的内存泄漏是指堆内 ...

  5. 进程间的通信方式(一):共享内存

    共享内存指 (shared memory)在多处理器的计算机系统中,可以被不同中央处理器(CPU)访问的大容量内存.由于多个CPU需要快速访问存储器,这样就要对存储器进行缓存(Cache).任何一个缓 ...

  6. 监视Rails进程内存泄漏的技巧

    Rails应用比较容易遇到的两类性能问题:一类是Rails执行很慢,CPU消耗过高:另一类是Rails进程内存泄漏.解决这两类问题都需要你首先能够精确定位出现问题的代码,然后才知道如何对症下药. 一. ...

  7. 【Linux进程、线程、任务调度】一 Linux进程生命周期 僵尸进程的含义 停止状态与作业控制 内存泄漏的真实含义 task_struct以及task_struct之间的关系

    学习交流加(可免费帮忙下载CSDN资源): 个人微信: liu1126137994 学习交流资源分享qq群1(已满): 962535112 学习交流资源分享qq群2: 780902027 文章目录 1 ...

  8. linux如何杀死进程最快,如何在Linux系统中杀掉内存消耗最大的进程?

    作为一名博客作者,我收藏了很多博客.网站和论坛用来寻找 Linux 和 Unix 相关的内容.有时候,我在浏览器中开启了非常多的标签页,导致操作系统会无响应好几分钟.我不能移动我的鼠标,也不能杀掉一个 ...

  9. 你的java程序有没有内存泄露,java进程在linux系统中rss计算方式是什么样的?

    java进程在linux系统中rss计算方式如下: RSS = Heap size + MetaSpace + OffHeap size 其中OffHeap由线程堆栈,直接缓冲区,映射文件(库和jar ...

最新文章

  1. 这本书,让我秒懂了微服务架构
  2. 25%的游戏通过Steam支持Linux系统
  3. extract_first()
  4. React文档(六)state和生命周期
  5. C语言-求字符串长度-strlen()与sizeof()
  6. Paper:《NÜWA: Visual Synthesis Pre-training for Neural visUal World creAtion,女娲:用于神经视觉世界创造的视觉》翻译与解读
  7. oracle授权with,ORACLE权限关于with admin option和with grant option的用法
  8. python urllib3 request 无返回结果_python urllib request urlopen请求网页返回bytes类型
  9. 点焊机器人焊接超时_「技术帖」FSW点焊技术在车身铝薄板焊接中的应用
  10. 命令行快速部署Exchange2010
  11. 大数据处理系统关键层次架构
  12. python读conf配置文件完成登录_python conf配置文件
  13. unix系统中查看端口号被占用
  14. 过年回家,还怕抢不到票?程序员教你如何抢票
  15. vue项目结合iview4UI组件实现树状结构及复杂动态表头列表 Tree-Table 及复杂header 省市区树状表格联动 数据优化后台一次性返回一万条数据页面卡死问题
  16. 多台电脑共享键盘鼠标
  17. 英文翻译法语-英文法语翻译软件
  18. Windows驱动_WSK驱动之四WSK例程
  19. 四大亮点不容错过,TDengine 开发者大会全议程公布!
  20. edt ast linux date,Linux 的时区修改.doc

热门文章

  1. Spring框架学习笔记11:基于Java配置方式SSM框架西蒙购物网
  2. mysqld占用mysql端口_IDEA连接不上MySQL端口号占用的解决
  3. layui表头样式_js相关:layui中table表头样式修改方法
  4. 【英语学习】【Level 07】U05 Best Destination L4 A perfect destination
  5. 【Linux使用】Centos 7 设置机器名/激活网络接口
  6. 【英语学习】【English L06】U04 Adventure L6 My favorite tourist destination
  7. linux下C\C++ 开发小笔记
  8. 虚拟服务器新建桌面池,VMware vSphere 服务器虚拟化之二十三 桌面虚拟化之建立手动虚拟桌面池...
  9. 进程间通信方式_第四十九期-Linux内核中的进程概述(4)
  10. eclipse中文乱码解决_Stata中文乱码顽疾解决方法-一行命令