记一次内存溢出查找的问题

Posted huangtao1927

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了记一次内存溢出查找的问题相关的知识,希望对你有一定的参考价值。

情景:今天测试环境发现应用出现内存溢出的问题。这是从来没有出现过的问题,在关闭此次版本新上线的功能后仍发现Perm区的内存持续在增长。

jdk版本:1.7

环境:linux

======================================================

起因:测试环境出现内存溢出

排查过程:

1,重现此内存溢出问题

查看应用日志,定位到哪一个操作导致内存溢出。发现是在调用接口之后出现。但由于测试环境有测试人员不断在部署版本,所以重启应用,再调用接口,发现无异常,于是使用JMeter多次请求接口,重现异常。

2,关闭此次版本功能

此次版本新上线的功能逐一关闭开关,定位是否是由新功能引起,发现关闭所有新功能开关后问题仍然存在

3,期间使用jdk自带工具分析应用状况与gc日志

<a>ps -ef | grep java      查看应用

<b>jstat -gcutil pid 1000    持续观察应用情况

<c>jmap -dump        把内存情况拷贝下来

<d>无gc日志

发现应用的启动脚本设置的启动参数有问题,于是重新设置启动参数与gc日志

重设的启动参数包括-Xmx,-Xms,-XX:PermSize,-XX:MaxPermSize和增加GC日志,垃圾回收器等

4,重设参数后,启动应用

继续使用jdk工具命令观察,发现Perm区一直在增长,FGC后也是一直增长,但是没有内存溢出

5,此期间怀疑有类在不断加载,或者缓存在不断增大

6,排查代码,发现不是缓存原因,很大可能是类在不断增加,但是这个就很奇异了

7,在开发环境重新部署应用,发现与测试环境的现象相同,于是又在开发环境重新部署上一个版本的应用,彻底排除是新增功能引起的问题,使用jdk自带工具观察,发现Perm区仍有增长

除了之前的工具,还使用jconsole连接应用,观察应用的情况

8,再次排查代码,并且使用两种方法测试

<a>,for循环10W次请求开发环境应用,观察应用的Perm区

<b>,测试应用,手动点击发送请求,请求开发环境应用

<c>,排查应用代码

=================================

结果:

在上一个版本中仍存在Perm区不断增长的问题,其实原因是代码中一直有classloader在作怪,无法释放类,并且在不断加载,只是从未被发现,此次是由于启动脚本缺失某些参数才暴露出的问题。所以需要去除相对应的代码

 

临时解决方案:

由于版本问题,无法修改代码,而Perm区的增长,到一定值之后,增长速度会非常缓慢,所以暂时决定先调整启动脚本,增大Perm区的大小,支撑到下一个版本修改代码

 

以上是关于记一次内存溢出查找的问题的主要内容,如果未能解决你的问题,请参考以下文章

记一次线上内存溢出问题排查过程

记一次java程序内存溢出问题

记一次java内存溢出的解决过程

JVM记一次PermGen space内存溢出实战案例

记一次 .NET 某妇产医院 WPF内存溢出分析

记一次内存溢出的分析经历 : thrift 带给我的痛