java内存泄漏的定位与分析
1、为什么会发生内存泄漏java 如何检测内在泄漏呢?我们需要一些工具进行检测,并发现内存泄漏问题,不然很容易发生down机问题。编写java程序最为方便的地方就是我们不需要管理内存的分配和释放,一切由jvm来进行处理,当java对象不再被应用时,等到堆内存不够用时,jvm会进行垃圾回收,清除这些对象占用的堆内存空间,如果对象一直被应用,jvm无法对其进行回收,创建新的对象时,无法从Heap中获取足够的内存分配给对象,这时候就会导致内存溢出。而出现内存泄露的地方,一般是不断的往容器中存放对象,而容器没有相应的大小限制或清除机制。容易导致内存溢出。当服务器应用占用了过多内存的时候,如何快速定位问题呢?现在,Eclipse MAT的出现使这个问题变得非常简单。EclipseMAT是著名的SAP公司贡献的一个工具,可以在Eclipse网站下载到它,完全免费的。要定位问题,首先你需要获取服务器jvm某刻内存快照。jdk自带的jmap可以获取内存某一时刻的快照,导出为dmp文件后,就可以用Eclipse MAT来分析了,找出是那个对象使用内存过多。2、内存泄漏的现象:常常地,程序内存泄漏的最初迹象发生在出错之后,在你的程序中得到一个OutOfMemoryError。这种典型的情况发生在产品环境中,而在那里,你希望内存泄漏尽可能的少,调试的可能性也达到最小。也许你的测试环境和产品的系统环境不尽相同,导致泄露的只会在产品中暴露。这种情况下,你需要一个低负荷的工具来监听和寻找内存泄漏。同时,你还需要把这个工具同你的系统联系起来,而不需要重新启动他或者机械化你的代码。也许更重要的是,当你做分析的时候,你需要能够同工具分离而使得系统不会受到干扰。一个OutOfMemoryError常常是内存泄漏的一个标志,有可能应用程序的确用了太多的内存;这个时候,你既不能增加JVM的堆的数量,也不能改变你的程序而使得他减少内存使用。但是,在大多数情况下,一个OutOfMemoryError是内存泄漏的标志。一个解决办法就是继续监听GC的活动,看看随时间的流逝,内存使用量是否会增加,如果有,程序中一定存在内存泄漏。3、发现内存泄漏1. jstat -gc pid可以显示gc的信息,查看gc的次数,及时间。其中最后五项,分别是young gc的次数,young gc的时间,full gc的次数,full gc的时间,gc的总时间。2.jstat -gccapacity pid可以显示,VM内存中三代(young,old,perm)对象的使用和占用大小,如:PGCMN显示的是最小perm的内存使用量,PGCMX显示的是perm的内存最大使用量,PGC是当前新生成的perm内存占用量,PC是但前perm内存占用量。其他的可以根据这个类推, OC是old内纯的占用量。3.jstat -gcutil pid统计gc信息统计。4.jstat -gcnew pid年轻代对象的信息。5.jstat -gcnewcapacity pid年轻代对象的信息及其占用量。6.jstat -gcold pidold代对象的信息。7.stat -gcoldcapacity pidold代对象的信息及其占用量。8.jstat -gcpermcapacity pidperm对象的信息及其占用量。9.jstat -class pid显示加载class的数量,及所占空间等信息。10.jstat -compiler pid显示VM实时编译的数量等信息。11.stat -printcompilation pid当前VM执行的信息。一些术语的中文解释:S0C:年轻代中第一个survivor(幸存区)的容量 (字节)S1C:年轻代中第二个survivor(幸存区)的容量 (字节)S0U:年轻代中第一个survivor(幸存区)目前已使用空间 (字节)S1U:年轻代中第二个survivor(幸存区)目前已使用空间 (字节)EC:年轻代中Eden(伊甸园)的容量 (字节)EU:年轻代中Eden(伊甸园)目前已使用空间 (字节)OC:Old代的容量 (字节)OU:Old代目前已使用空间 (字节)PC:Perm(持久代)的容量 (字节)PU:Perm(持久代)目前已使用空间 (字节)YGC:从应用程序启动到采样时年轻代中gc次数YGCT:从应用程序启动到采样时年轻代中gc所用时间(s)FGC:从应用程序启动到采样时old代(全gc)gc次数FGCT:从应用程序启动到采样时old代(全gc)gc所用时间(s)GCT:从应用程序启动到采样时gc用的总时间(s)NGCMN:年轻代(young)中初始化(最小)的大小 (字节)NGCMX:年轻代(young)的最大容量 (字节)NGC:年轻代(young)中当前的容量 (字节)OGCMN:old代中初始化(最小)的大小 (字节)OGCMX:old代的最大容量 (字节)OGC:old代当前新生成的容量 (字节)PGCMN:perm代中初始化(最小)的大小 (字节)PGCMX:perm代的最大容量 (字节)PGC:perm代当前新生成的容量 (字节)S0:年轻代中第一个survivor(幸存区)已使用的占当前容量百分比S1:年轻代中第二个survivor(幸存区)已使用的占当前容量百分比E:年轻代中Eden(伊甸园)已使用的占当前容量百分比O:old代已使用的占当前容量百分比P:perm代已使用的占当前容量百分比S0CMX:年轻代中第一个survivor(幸存区)的最大容量 (字节)S1CMX :年轻代中第二个survivor(幸存区)的最大容量 (字节)ECMX:年轻代中Eden(伊甸园)的最大容量 (字节)DSS:当前需要survivor(幸存区)的容量 (字节)(Eden区已满)TT:持有次数限制MTT :最大持有次数限制如果定位内存泄漏问题我一般使用如下命令:Jstat -gcutil15469 2500 70如果有大量的FGC就要查询是否有内存泄漏的问题了,图中的FGC数量就比较大,并且执行时间较长,这样就会导致系统的响应时间较长,如果对jvm的内存设置较大,那么执行一次FGC的时间可能会更长。如果为了更好的证明FGC对服务器性能的影响,我们可以使用java visualVM来查看一下:从上图可以发现执行FGC的情况,下午3:10分之前是没有FGC的,之后出现大量的FGC。上图是jvm堆内存的使用情况,下午3:10分之前的内存回收还是比较合理,但是之后大量内存无法回收,最后导致内存越来越少,导致大量的full gc。下面我们在看看大量full GC 对服务器性能的影响,下面是我用loadrunner对我们项目进行压力测试相应时间的截图:从图中可以发现有,在进行full GC 后系统的相应时间有了明显的增加,点击率和吞吐量也有了明显的下降。所以java内存泄漏对系统性能的影响是不可忽视的。3、定位内存泄漏当然通过上面几种方补充:软件开发 , Java ,
上一个:java源码分析之ArrayList
下一个:java 获取网页源代码
- 更多JAVA疑问解答:
- java怎么在线读取ftp服务器上的文件内容
- 关于程序员的职业规划
- HTML和JSP矛盾吗?
- java小程序如何打包?
- java怎么split路径文件名?
- jsp+javaBean中Column 'ordersPrice' specified twice的错误
- Java TCP/IP Socket网络编程系列
- 大家来讨论一下我到底该用什么好?Swing 还是 JavaFX
- 关于Hibernate实体自身多对一的抓取问题
- 关于apache2+tomcat群集出现的问题
- spring 获取上下文问题
- SSH 导入导出excel 谁有这块的资料吗?
- Ext TreePanel 刷新问题
- springmvc 加载一个jsp页面执行多个方法 报404
- checkbox数组action怎么向页面传值