java内存泄漏的定位与分析 Myth丶恋晨 2022-05-14 05:22 133阅读 0赞 # **1、为什么会发生内存泄漏** # Java如何检测内在泄漏呢?我们需要一些工具进行检测,并发现内存泄漏问题,不然很容易发生down机问题。 编写java程序最为方便的地方就是我们不需要管理内存的分配和释放,一切由jvm来进行处理,当java对象不再被应用时,等到堆内存不够用时,jvm会进行垃圾回收,清除这些对象占用的堆内存空间,如果对象一直被应用,jvm无法对其进行回收,创建新的对象时,无法从Heap中获取足够的内存分配给对象,这时候就会导致内存溢出。而出现内存泄露的地方,一般是不断的往容器中存放对象,而容器没有相应的大小限制或清除机制。容易导致内存溢出。 当服务器应用占用了过多内存的时候,如何快速定位问题呢?现在,**Eclipse MAT **的出现使这个问题变得非常简单。Eclipse MAT是著名的SAP公司贡献的一个工具,可以在Eclipse网站下载到它,完全免费的。 要定位问题,首先你需要获取服务器jvm 某刻内存快照。jdk 自带的jmap 可以获取内存某一时刻的快照,导出为dump 文件后,就可以用Eclipse MAT 来分析了,找出是那个对象使用内存过多。 # **2、内存泄漏的现象** # 常常地,程序内存泄漏的最初迹象发生在出错之后,在你的程序中得到一个OutOfMemoryError。这种典型的情况发生在产品环境中,而在那里,你希望内存泄漏尽可能的少,调试的可能性也达到最小。也许你的测试环境和产品的系统环境不尽相同,导致泄露的只会在产品中暴露。这种情况下,你需要一个低负荷的工具来监听和寻找内存泄漏。同时,你还需要把这个工具同你的系统联系起来,而不需要重新启动他或者机械化你的代码。也许更重要的是,当你做分析的时候,你需要能够同工具分离而使得系统不会受到干扰。 一个OutOfMemoryError 常常是内存泄漏的一个标志,有可能应用程序的确用了太多的内存;这个时候,你既不能增加JVM的堆的数量,也不能改变你的程序而使得他减少内存使用。但是,在大多数情况下,一个OutOfMemoryError 是内存泄漏的标志。一个解决办法**就是继续监听GC 的活动**,看看随时间的流逝,内存使用量是否会增加,如果有,程序中一定存在内存泄漏。 # **3、发现内存泄漏** # **3.1. jstat -gc pid** 可以显示gc的信息,查看gc的次数,及时间。 其中最后五项,分别是young gc的次数,young gc的时间,full gc的次数,full gc的时间,gc的总时间。 **3.2. jstat -gccapacity pid** 可以显示,VM内存中三代(young,old,perm)对象的使用和占用大小, 如:PGCMN显示的是最小perm的内存使用量,PGCMX显示的是perm的内存最大使用量, PGC是当前新生成的perm内存占用量,PC是但前perm内存占用量。 其他的可以根据这个类推,OC是old内纯的占用量。 **3.3. jstat -gcutil pid** 统计gc信息统计。 **3.4. jstat -gcnew pid** 年轻代对象的信息。 **3.5. jstat -gcnewcapacity pid** 年轻代对象的信息及其占用量。 **3.6. jstat -gcold pid** old代对象的信息。 **3.7. jstat -gcoldcapacity pid** old代对象的信息及其占用量。 **3.8. jstat -gcpermcapacity pid** perm对象的信息及其占用量。 **3.9. jstat -class pid** 显示加载class的数量,及所占空间等信息。 **3.10. jstat -compiler pid** 显示VM实时编译的数量等信息。 **3.11. jstat -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) 如果定位内存泄漏问题我一般使用如下命令: jstat -gcutil 15469 2500 70 ![20180903152531889][] [root@izbp16djex81rgji9ycnyfz app]# jstat -gcutil 22120 1000 300 S0 S1 E O M CCS YGC YGCT FGC FGCT GCT 0.00 76.47 69.45 35.63 94.94 92.29 999 6.664 3 0.418 7.082 0.00 76.47 72.91 35.63 94.94 92.29 999 6.664 3 0.418 7.082 0.00 76.47 73.88 35.63 94.94 92.29 999 6.664 3 0.418 7.082 0.00 76.47 73.88 35.63 94.94 92.29 999 6.664 3 0.418 7.082 0.00 76.47 73.88 35.63 94.94 92.29 999 6.664 3 0.418 7.082 0.00 76.47 73.88 35.63 94.94 92.29 999 6.664 3 0.418 7.082 0.00 76.47 76.09 35.63 94.94 92.29 999 6.664 3 0.418 7.082 0.00 76.47 78.30 35.63 94.94 92.29 999 6.664 3 0.418 7.082 0.00 76.47 78.30 35.63 94.94 92.29 999 6.664 3 0.418 7.082 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数量就比较大(这里并不是原图,上面那个是原图,FGC在六百多),并且执行时间较长,这样就会导致系统的响应时间较长,如果对jvm的内存设置较大,那么执行一次FGC的时间可能会更长。 # **4、定位内存泄漏** # 当然通过上面几种方法我们可以发现java的内存泄漏问题,但是作为一名合格的高级工程师,肯定不甘心就把这样的结论交给开发,当然这也的结论交给开发,开发也很难定位问题,为了更好的提供自己在公司的地位,我们必须给开发工程师提供更深入的测试结论,下面就来认识一下**MemoryAnalyzer.exe**。java内存泄漏检查工具利器。 首先我们必须对jvm的堆内存进行dump,只有拿到这个文件我们才能分析出jvm堆内存中到底存了些什么内容,到底在做什么? MemoryAnalyzer的用户我在这里就不一一说明了,我的博客里也有说明,下面就展示我测试的成功图: ![2018090315304019][] 其中深蓝色的部分就为内存泄漏的部分,java的堆内存一共只有481.5M而内存泄漏的部分独自占有了336.2M所以本次的内存泄漏很明显,那么我就来看看那个方法导致的内存泄漏: ![20180903153103105][] 从上图我们可以发现红线圈着的方法占用了堆内存的67.75%,如果能把这个测试结果交给开发,开发是不是应该很好定位呢。所以作为一名高级测试工程师,我们需要学习的东西太多。 虽然不确定一定是内存泄漏,但是可以准确的告诉开发问题出现的原因,有一定的说服力。 -------------------- 转自:[http://www.kuqin.com/shuoit/20160603/352307.html][http_www.kuqin.com_shuoit_20160603_352307.html] [20180903152531889]: /images/20220514/9eaed24df0dc453b8deb42bb421cec11.png [2018090315304019]: /images/20220514/706aa6a2122f4ebb9fcf46092944022d.png [20180903153103105]: /images/20220514/f78e762e9d8e46dd80a8047d8116987f.png [http_www.kuqin.com_shuoit_20160603_352307.html]: http://www.kuqin.com/shuoit/20160603/352307.html
相关 解决Java内存泄漏问题:实例与分析 Java内存泄漏是程序在使用内存后,无法释放已申请的内存空间,导致系统可用内存持续减少,严重影响应用性能和系统的稳定性。 解决Java内存泄漏的问题通常需要以下步骤: 1. ╰半橙微兮°/ 2024年09月12日 11:51/ 0 赞/ 31 阅读
相关 Java内存泄漏分析与防止实例 在Java编程中,内存泄漏是一个常见的问题。简单来说,内存泄漏就是程序无法释放已经申请但是不再使用的内存在系统中累积的现象。 以下是进行Java内存泄漏分析及防止的一些实例: ゝ一世哀愁。/ 2024年09月10日 05:03/ 0 赞/ 24 阅读
相关 Java内存泄漏问题分析与实践 Java内存泄漏是指程序在申请内存后,无法释放已申请的内存空间,导致系统可用内存逐渐减少。这个问题不仅会影响系统的性能,严重时甚至可能导致系统崩溃。 以下是一些分析和实践方法 谁借莪1个温暖的怀抱¢/ 2024年09月05日 21:09/ 0 赞/ 11 阅读
相关 linux通过meminfo 与 slab 定位内存泄漏 https://www.jianshu.com/p/a7af7c29c9e2 前言 问题真是一个接一个,做开发就是解决一个又一个问题吗? 像死机、内存泄漏这些问题很多 ゞ 浴缸里的玫瑰/ 2023年01月18日 13:25/ 0 赞/ 323 阅读
相关 java内存泄漏的定位与分析 1、为什么会发生内存泄漏 Java如何检测内在泄漏呢?我们需要一些工具进行检测,并发现内存泄漏问题,不然很容易发生down机问题。 编写java程序最为方便的地方就是我 Myth丶恋晨/ 2022年05月14日 05:22/ 0 赞/ 134 阅读
相关 一次JAVA内存泄漏的定位分析过程 正式环境老是内存用完崩溃。 在本地模拟以及解决过程 查询JAVA线程,命令:jps -lvm ![70][] 生成dump文件:jmap -dump: 深藏阁楼爱情的钟/ 2022年05月13日 22:12/ 0 赞/ 196 阅读
相关 java内存泄漏的定位与分析 1、为什么会发生内存泄漏 Java如何检测内在泄漏呢?我们需要一些工具进行检测,并发现内存泄漏问题,不然很容易发生down机问题。 编写java程序最为方便的地方就是我们不 朴灿烈づ我的快乐病毒、/ 2022年05月13日 03:18/ 0 赞/ 153 阅读
相关 【转】java内存泄漏的定位与分析 1、为什么会发生内存泄漏 Java如何检测内在泄漏呢?我们需要一些工具进行检测,并发现内存泄漏问题,不然很容易发生down机问题。 编写java程序最为方便的地方就是我们不 ╰+攻爆jí腚メ/ 2022年05月11日 19:18/ 0 赞/ 147 阅读
相关 java内存泄漏的定位与分析 转载自: [https://blog.csdn.net/gzh0222/article/details/8538727][https_blog.csdn.net_gzh0222 阳光穿透心脏的1/2处/ 2022年04月11日 07:49/ 0 赞/ 272 阅读
还没有评论,来说两句吧...