定位java内存无限上涨问题

  最近一直在做性能优化方面的工作,填填项目快跑过程中留下的坑。越底层的愈是枯燥的,也越感受到欣喜。下面分享给读者一个java服务吃掉常驻内存(RES)的case,希望能对大家带来收获。

定位java内存无限上涨问题_第1张图片

在容器内跑的java服务,参数为

java -Xms128M -Xmx128M -Xmn32M -Xss256K -XX:+UseG1GC

经常莫名的oom killer,如下图

 

定位java内存无限上涨问题_第2张图片

也就是说此进程的内存使用超过了256Mi。

如果要解决这个case,快速修复的办法是调高容器的memory上限。但此服务是个很轻量级的watcher服务,jvm参数xmx设置的是128M,设置之初肯定没有想到内存占用会超过堆内存的2倍。

所以只有找到内存都分配给谁了才能找到真相。。。

 

定位java内存无限上涨问题_第3张图片

1:是否堆内存溢出?

    查看堆内存的使用情况,发现内存使用率很健康

定位java内存无限上涨问题_第4张图片

    GC的次数也顺便瞅一眼,也非常的健康

定位java内存无限上涨问题_第5张图片

所以很快就能排除是堆的内存泄露。

其实不用经过这一步就能知道不是堆出现了问题,大家细想一下是为什么。

 

定位java内存无限上涨问题_第6张图片

    如图,发现了80个netty的work线程(条件发射知道这一块肯定是可优化的,不管是不是与内存优化相关)。

定位java内存无限上涨问题_第7张图片

使用jstack和jmap定时统计和分析,也没发现有什么问题。

 

由于在容器内并且是线上,很多命令无法使用,也不敢使用,所以我将服务迁移部署到物理机上,下面可以肆无忌惮的操作了。

使用linux系统内存分析命令pmap,得到的对象总和:

                             Kbytes     RSS   Dirty

    total kB         13140048  299996  285216

与使用命令 top -p 35389, 差不多能对应上

定位java内存无限上涨问题_第8张图片

pmap得到的信息很详细,我具体累加了每一块的消耗内存。

定位java内存无限上涨问题_第9张图片

得出如下数字:

    a:heap大小:128M

    b:jvm依赖:13036Ki(12M)

    c:项目依赖 1488ki

    d:系统级别依赖:1200ki

   e:anon,匿名内存

除了anon外,其他都看了没发现问题,而增长的部分就是在annon,由于annon这一块使用jmap已经无法进一步定位问题了。

使用jvm内存调试工具jcmd继续分析。

这个命令可用于监控JVM原生内存的使用,并且可以设置baseline,可以根据baseline来进行sumary报告,不需要我额外写定时执行脚本了,非常的方便。

 

        余下文章,请关注公众号,继续阅读

定位java内存无限上涨问题_第10张图片

你可能感兴趣的:(JAVA学习)