java内存泄漏的定位与分析 阳光穿透心脏的1/2处 2022-04-11 07:49 295阅读 0赞 转载自: [https://blog.csdn.net/gzh0222/article/details/8538727][https_blog.csdn.net_gzh0222_article_details_8538727] ** ** **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 pid old代对象的信息。 7.stat -gcoldcapacity pid old代对象的信息及其占用量。 8.jstat -gcpermcapacity pid perm对象的信息及其占用量。 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 ![1359016537_4486.jpg][] \[root@ssss logs\]\# jstat -gcutil 15469 1000 300 S0 S1 E O P YGC YGCT FGC FGCT GCT 0.00 1.46 26.54 4.61 30.14 35 0.872 0 0.000 0.872 0.00 1.46 46.54 4.61 30.14 35 0.872 0 0.000 0.872 0.00 1.46 47.04 4.61 30.14 35 0.872 0 0.000 0.872 0.00 1.46 65.19 4.61 30.14 35 0.872 0 0.000 0.872 0.00 1.46 67.54 4.61 30.14 35 0.872 0 0.000 0.872 0.00 1.46 87.54 4.61 30.14 35 0.872 0 0.000 0.872 0.00 1.46 88.03 4.61 30.14 35 0.872 0 0.000 0.872 1.48 0.00 5.56 4.62 30.14 36 0.874 0 0.000 0.874 1000 代表多久间隔显示一次, 100 代表显示一次。 S0 — Heap上的 Survivor space 0 区已使用空间的百分比 S1 — Heap上的 Survivor space 1 区已使用空间的百分比 E — Heap上的 Eden space 区已使用空间的百分比 O — Heap上的 Old space 区已使用空间的百分比 P — Perm space 区已使用空间的百分比 YGC — 从应用程序启动到采样时发生 Young GC 的次数 YGCT– 从应用程序启动到采样时 Young GC 所用的时间(单位秒) FGC — 从应用程序启动到采样时发生 Full GC 的次数 FGCT– 从应用程序启动到采样时 Full GC 所用的时间(单位秒) GCT — 从应用程序启动到采样时用于垃圾回收的总时间(单位秒) 如果有大量的FGC就要查询是否有内存泄漏的问题了,图中的FGC数量就比较大,并且执行时间较长,这样就会导致系统的响应时间较长,如果对jvm的内存设置较大,那么执行一次FGC的时间可能会更长。 如果为了更好的证明FGC对服务器性能的影响,我们可以使用java visualVM来查看一下: ![1359016555_1348.jpg][] 从上图可以发现执行FGC的情况,下午3:10分之前是没有FGC的,之后出现大量的FGC。 上图是jvm堆内存的使用情况,下午3:10分之前的内存回收还是比较合理,但是之后大量内存无法回收,最后导致内存越来越少,导致大量的full gc。 下面我们在看看大量full GC对服务器性能的影响,下面是我用loadrunner对我们项目进行压力测试相应时间的截图: ![1359016576_6204.jpg][] 从图中可以发现有,在进行full GC后系统的相应时间有了明显的增加,点击率和吞吐量也有了明显的下降。所以java内存泄漏对系统性能的影响是不可忽视的。 **3、定位内存泄漏** 当然通过上面几种方法我们可以发现java的内存泄漏问题,但是作为一名合格的高级工程师,肯定不甘心就把这样的结论交给开发,当然这也的结论交给开发,开发也很难定位问题,为了更好的提供自己在公司的地位,我们必须给开发工程师提供更深入的测试结论,下面就来认识一下MemoryAnalyzer.exe。java内存泄漏检查工具利器。 首先我们必须对jvm的堆内存进行dump,只有拿到这个文件我们才能分析出jvm堆内存中到底存了些什么内容,到底在做什么? MemoryAnalyzer的用户我在这里就不一一说明了,我的博客里也有说明,下面就展示我测试的成功图: ![1359016621_3561.jpg][] 其中深蓝色的部分就为内存泄漏的部分,java的堆内存一共只有481.5M而内存泄漏的部分独自占有了336.2M所以本次的内存泄漏很明显,那么我就来看看那个方法导致的内存泄漏: ![1359016648_4268.jpg][] 从上图我们可以发现红线圈着的方法占用了堆内存的67.75%,如果能把这个测试结果交给开发,开发是不是应该很好定位呢。所以作为一名高级测试工程师,我们需要学习的东西太多。 虽然不确定一定是内存泄漏,但是可以准确的告诉开发问题出现的原因,有一定的说服力。 本人刚刚完成了云存储架构师的培训学习(包括了linux的内核了解、 shell的高级编程、linux安全的学习重点iptables和tcp/ip等各种协议的抓包分析、linux的集群、性能调优等接下来还有dba的课程等待着我挑战)。 ** ** [https_blog.csdn.net_gzh0222_article_details_8538727]: https://blog.csdn.net/gzh0222/article/details/8538727 [1359016537_4486.jpg]: https://img-my.csdn.net/uploads/201301/24/1359016537_4486.jpg [1359016555_1348.jpg]: https://img-my.csdn.net/uploads/201301/24/1359016555_1348.jpg [1359016576_6204.jpg]: https://img-my.csdn.net/uploads/201301/24/1359016576_6204.jpg [1359016621_3561.jpg]: https://img-my.csdn.net/uploads/201301/24/1359016621_3561.jpg [1359016648_4268.jpg]: https://img-my.csdn.net/uploads/201301/24/1359016648_4268.jpg
相关 Java内存泄漏问题分析与解决 在Java编程中,内存泄漏是一个常见的问题。它会导致系统可用的内存逐渐减少,从而影响程序的性能和稳定性。 内存泄漏的主要类型包括: 1. 对象引用:当一个对象被创建,但其引 拼搏现实的明天。/ 2024年10月15日 13:42/ 0 赞/ 32 阅读
相关 Java内存泄漏原因与案例分析 Java内存泄漏是指在程序运行过程中,程序申请的内存没有被释放,导致系统可用内存逐渐减少,严重时可能导致应用程序崩溃。 内存泄漏的原因主要有以下几种: 1. 对象生命周期管 野性酷女/ 2024年10月10日 06:30/ 0 赞/ 48 阅读
相关 Java内存泄漏分析与防止实例 在Java编程中,内存泄漏是一个常见的问题。简单来说,内存泄漏就是程序无法释放已经申请但是不再使用的内存在系统中累积的现象。 以下是进行Java内存泄漏分析及防止的一些实例: ゝ一世哀愁。/ 2024年09月10日 05:03/ 0 赞/ 56 阅读
相关 Java内存泄漏问题分析与实践 Java内存泄漏是指程序在申请内存后,无法释放已申请的内存空间,导致系统可用内存逐渐减少。这个问题不仅会影响系统的性能,严重时甚至可能导致系统崩溃。 以下是一些分析和实践方法 谁借莪1个温暖的怀抱¢/ 2024年09月05日 21:09/ 0 赞/ 43 阅读
相关 java内存泄漏的定位与分析 1、为什么会发生内存泄漏 Java如何检测内在泄漏呢?我们需要一些工具进行检测,并发现内存泄漏问题,不然很容易发生down机问题。 编写java程序最为方便的地方就是我 Myth丶恋晨/ 2022年05月14日 05:22/ 0 赞/ 155 阅读
相关 一次JAVA内存泄漏的定位分析过程 正式环境老是内存用完崩溃。 在本地模拟以及解决过程 查询JAVA线程,命令:jps -lvm ![70][] 生成dump文件:jmap -dump: 深藏阁楼爱情的钟/ 2022年05月13日 22:12/ 0 赞/ 219 阅读
相关 java内存泄漏的定位与分析 1、为什么会发生内存泄漏 Java如何检测内在泄漏呢?我们需要一些工具进行检测,并发现内存泄漏问题,不然很容易发生down机问题。 编写java程序最为方便的地方就是我们不 朴灿烈づ我的快乐病毒、/ 2022年05月13日 03:18/ 0 赞/ 182 阅读
相关 【转】java内存泄漏的定位与分析 1、为什么会发生内存泄漏 Java如何检测内在泄漏呢?我们需要一些工具进行检测,并发现内存泄漏问题,不然很容易发生down机问题。 编写java程序最为方便的地方就是我们不 ╰+攻爆jí腚メ/ 2022年05月11日 19:18/ 0 赞/ 166 阅读
相关 java内存泄漏的定位与分析 转载自: [https://blog.csdn.net/gzh0222/article/details/8538727][https_blog.csdn.net_gzh0222 阳光穿透心脏的1/2处/ 2022年04月11日 07:49/ 0 赞/ 296 阅读
还没有评论,来说两句吧...