JVM 内存泄漏场景

介绍案例前,先了解一下内存泄漏和内存溢出的区别。
内存溢出:程序没有足够的内存使用时,就会发生内存溢出。内存溢出后程序基本上就无法正常运行了。
内存泄漏:当程序不能及时释放内存,导致占用内存逐渐增加,就是内存泄漏。内存泄漏一般不会导致程序无法运行。不过持续的内存泄漏,累积到内存上限时,就会发生内存溢出。在Java中,如果发生内存泄漏,会导致GC回收不彻底,每次GC后,堆内存使用率逐渐增高。下图是JVM发生内存泄漏的监控图,我们可以看到每次GC后堆内存使用率都比以前提高了。

当时内存泄漏的场景是,用本地缓存(公司基础架构组自己研发的框架)存放了商品数据,商品数量不算太多,几十万的样子。如果只存热点商品,内存占用不会太大,但是如果存放全量商品,内存就不够了。初期我们给每个缓存记录都加了7天的过期时间,这样就可以保证缓存中绝大部分都是热点商品。不过后来本地缓存框架经过一次重构,过期时间被去掉了。没有了过期时间,日积月累本地缓存越来越大,很多冷数据也被加载到了缓存。直到有一天接到告警短信,提示堆内存过高。赶紧通过jmap(jmap -dump:format=b,file=文件名 [pid] )下载了堆内存快照,然后用eclipse的 mat工具分析快照,发现了本地缓存中有大量的商品记录。定位问题后赶紧让架构组加上了过期时间,然后逐个节点重启了服务。

亏了我们加了服务器内存和 JVM堆内存监控,及时发现了内存泄漏的问题。否则随着泄漏问题日积月累,如果哪天真的 OOM就惨了。所以技术团队除了做好 CPU,内存等运维监控,JVM监控也非常重要。

猜你喜欢

转载自blog.csdn.net/zhengzhaoyang122/article/details/106999675
今日推荐