为什么老年代内存在一直上升?

最近看到 Grafana 监控大屏中,负责的一个服务的两个节点中, Old Generation 内存都再稳步上升,并且并未触发 Major GC,此时好奇心起,到底是应用中的哪些操作产生了这样的影响呢?

随后我联系运维同事,帮忙导出 dump 文件,选择了 Pod 1执行命令 jmap -<img src="dump" alt="" width="50%" />:live,format=b,file=heap001

Pod 1 执行的 dump 命令后,Old Gen 内存走势如图:

可以看到,此次 dump 引发了一次 Major GC(Heap Dump Initlated),Old Gen 内存迅速被释放,因此可以推断出,此服务实例之前的老年代存在大量垃圾对象,因为未触发 Major GC,导致这些对象一直占用内存未被及时清除。

那到底是哪些对象一直源源不断地进入老年代呢?

Pod 2 和 Pod 1 的资源配置情一致,并且 Old Gen 内存走势也大致相同,随后让运维同事在 Pod 2 执行 dump 命令: jmap -dump:format=b,file=heap002 , 除了生成的文件名称和 Pod 1 不一样外,火眼金睛的你应该也已经发现,此次命令少了个可选参数 live ,这样生成内存快照前并不会触发 Full GC,利于我们观察垃圾对象的情况。

利用 IDEA 的一款插件 Profiler 分析下 heap dump 文件。

观察 Class Tab 页,根据 Shallow 从大到小排列(Shalllow 表示这个对象占用堆的大小,Retained 表示下一次 Major GC 后对象在堆中的大小)。和业务代码直接相关的两个类 ApplicationBankRegionTree ,可以明显的看到,这两个类的实例存在近 140M 的垃圾对象未被回收。那么这下可以精确地找到相关类,从而顺藤摸瓜找到关键业务代码:

RegionTree 同样也有对应的缓存。看到这些代码,想必结论也清楚了:每隔 30 min 刷新一遍 LocalCache 缓存,这些缓存实例也算是长期存活的对象了,它们或因年龄到达准入年龄(默认15岁),或因动态年龄判定机制,或因空间分配担保机制进入老年代也是正常现象。

至此,Old Gen 内存缓慢上升的原因,已显露水面,JVM 内存中存在一些长期存活的缓存对象在内存中,并且这些缓存对象每隔一段时间都会重新生成新的实例,随着应用运行的时间越来越长,转入老年代的业务缓存实例也越来越多,最终就会呈现出 Old Gen 内存上升的现象。

那么这样的现象会对应用产生什么影响吗?从目前应用运行的状态来看,即使内存缓慢增长也未触发 Major GC,说明这些缓存对象集合实例并不大,即使经过很长一段时间,达到了 Old Gen 内存限制,那么就会发生 Major GC 来清理这些垃圾,这也是正常现象。而目前此应用发生的 Major GC 次数非常少。所以此应用的内存情况是正常的。

判断应用内存情况,我们可以从应用的 Heap 内存使用大小、 Heap 内存是否可通过 GC 释放掉、 GC 频率以及耗时情况等方面入手。当发现有内存问题时,可使用 jmap 命令获取 JVM 内存快照,并配合一些 dump 分析工具(Profiler、Yourkit(Paid))对内存进行深入分析,找到问题所在。

Reference

相关推荐
吴声子夜歌2 小时前
ApacheCommons——commons-pool2(高性能通用对象池框架)
java·开发语言·apache
mldong6 小时前
C# 开发者也有自己的轻量工作流引擎了:NuGet 装包,5 分钟跑通一条审批流
后端·c#·.net
xcl09257 小时前
幼儿托育系统开发实战:从需求分析到上线全流程指南
java·大数据·需求分析
吴声子夜歌7 小时前
ApacheCommons——commons-cli(命令行参数解析)
java·开发语言·apache
小小猪的春天7 小时前
Java 手写第一个 MCP Server:Spring AI MCP 半小时跑通
java·人工智能·spring boot·ai编程
find1star7 小时前
LeetCode 141:环形链表
java·算法·leetcode·链表
爱学堂IT分享8 小时前
鹤翔老师pmp项目管理培训认证考试课 (直播录播题库送学时证明)【共58课时】-51CTO学堂
后端
今天AI了吗8 小时前
DeepSeek Harness 深度解析:从评测架构到实战落地
java·网络·数据库·人工智能·架构·java-ee
王的宝库8 小时前
Go 项目结构:从单文件到标准工程布局
开发语言·后端·golang
许彰午8 小时前
27-AuthService登录链路
java·低代码·架构