内存泄漏定位

2020-09-28 10:00:06 浏览数 (1)

Java如何检测内在泄漏呢?我们需要一些工具进行检测,并发现内存泄漏问题。

编写java程序最为方便的地方就是我们不需要管理内存的分配和释放,一切由jvm来进行处理,当java对象不再被应用时,等到堆内存不够用时,jvm会进行垃圾回收,清除这些对象占用的堆内存空间,如果对象一直被应用,jvm无法对其进行回收,创建新的对象时,无法从Heap中获取足够的内存分配给对象,这时候就会导致内存溢出。

而出现内存泄露的地方,一般是不断的往容器中存放对象,而容器没有相应的大小限制或清除机制。容易导致内存溢出。当服务器应用占用了过多内存的时候,如何快速定位问题呢?

我们先来了解几个知识点:

设置每个线程栈大小:-Xss10M

改变栈的大小:

1、可以调整线程的调用层次

2、可以控制虚拟机运行的线程数

常见错误:java.lang.StackOverflowError:栈空间不足

垃圾回收算法:

分代处理

年轻代

伊甸区--eden

幸存区

年老代

改变堆大小:

-Xms--初始堆内存大小

-Xmx--最大堆内存大小

设置规则:-Xms=-Xmx

内存泄漏定位:--

OutofMemoryError产生的原因:

1、内存泄漏

2、堆内存不足

判定内存泄漏的方法:

1、在压力稳定的情况下监控堆内存的变化。

2、监控堆内存使用情况,如果发现堆内存有不断增加的趋势,初步可以判断内存泄漏。

3、在压力稳定过程中(时间较长),对堆内存做dump。

生成堆的dump文件:通过JMX的MBean生成当前的Heap信息,大小为一个3G(整个堆的大小)的hprof文件,如果没有启动JMX可以通过Java的jmap命令来生成该文件。

4、借助于MAT分析dump文件,观察对象使用情况

EclipseMAT是SAP公司贡献的一个工具,可以在Eclipse网站下载到它,完全免费的。 要定位问题,首先你需要获取服务器jvm某刻内存快照。jdk自带的jmap可以获取内存某一时刻的快照,导出为dmp文件后,就可以用Eclipse MAT来分析了,找出是那个对象使用内存过多。

堆内存分析:

1、哪些对象一直在增加?借助于工具的增量功能

2、找到重点对象(增加速度和大小都比较大的)

3、分析对象之间的关系--out in

4、分析这些对象是哪些线程产生的?分析dump的线程数据

5、分析线程栈,定位代码

堆dump,一定在服务器端完成,不要借助于网络工具:jmap

通过Mat我们能清楚地看到,哪些对象被怀疑为内存泄漏,哪些对象占的空间最大及对象的调用关系。另,通过Mat或JMX我们还可以分析线程状态,可以观察到线程被阻塞在哪个对象上,从而判断系统的瓶颈。

正常的堆空间垃圾回收图示JVM和Visual GC:

程序出现异常的堆空间垃圾回收图示JVM和Visual GC:

0 人点赞