【VisualVM 简明教程】(2):分析堆内存OOM

发布时间:2019-11-19 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了【VisualVM 简明教程】(2):分析堆内存OOM脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。

主要功能

  • 概述

显示jvm运行时的参数,Java版本,以及系统属性。

  • 监控

显示当前这个pid的cpu,堆,PErmGen,类,线程的运行情况,可以主动进行垃圾回收,以及生成此时刻的dump文件。

  • 线程

显示所有线程的“实时”状态(运行,休眠,等待,监视)以及时间,(调整好刷新时间),可以通过放大,放小,更细致的观察线程的状态,以及一个线程详细的时刻状态和线程dump堆栈。

  • 抽样器

随机抽样快速检测,显示各个方法和线程的cpu耗时,以及堆区各个实例、方法区各个类、以及每个线程所占内存详细信息。

功能和抽样器差不多,只不过是全面检测,比较慢而已(类似杀毒软件的快速扫描和全盘扫描)。

OOM在JVM中发生的地方只有堆,栈,方法区,直接内存。
Java程序大多发生OOM是在堆区域,堆dump 是分析内存堆的唯一文件,可以由VisualVm,IBM HeapAnalyzer,Jhat,Eclipse MemoryAnalyzer等分析,这里单独介绍VisuaLVM

案例:堆内存的OOM

设置JVM 启动参数 -XMX1024m -Xms1024m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=d:dump (其中堆 1,073,741,824个字节,字节与m相差大约6个倍数)运行下面程序,则会发生OOM的时候,生成堆文件,目录在D盘dump文件夹下(或者设置VisualVm中右键该应用,发生OOME自动生成dump)。

当然生产的时候,并不是等到OOM才生成dump文件,直接用jmap -dump:format=b,file=xxx.hprof 24331 jmap是jdk自带工具,format=b是代表二进制,file代表生成路径 24331代表pid,可以用 ps -ef | grep 进程名 找到 ,当然jmap还有很多功能,查看JVM堆对象占用情况,JVM内存状态等,这里不多介绍。

package jvisualVM;   public class JavaHeapTest {     public final static int OUTOFMEMORY = 900000000;       private String oom;       private int length;       StringBuffer tempOOM = new StringBuffer();       public JavaHeapTest(int leng) {         this.length = leng;           int i = 0;         while (i < leng) {             i++;             try {                 tempOOM.append("a");             } catch (OutOfMemoryError e) {                e.printStackTrace();                break;             }         }         this.oom = tempOOM.toString();       }       public String getOom() {         return oom;     }       public int getLength() {         return length;     }       public static void main(String[] args) {         JavaHeapTest javaHeapTest = new JavaHeapTest(OUTOFMEMORY);         System.out.println(javaHeapTest.getOom().length());     }   }

输出:

java.lang.OutOfMemoryError: Java heap space Dumping heap to d:dumpjava_pid10024.hprof ... Heap dump file created [606447327 bytes in 1.577 secs] java.lang.OutOfMemoryError: Java heap space     at java.util.Arrays.copyOf(Arrays.java:2367)     at java.lang.AbstractStringBuilder.expandCapacity(AbstractStringBuilder.java:130)     at java.lang.AbstractStringBuilder.ensureCapacityInternal(AbstractStringBuilder.java:114)     at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:415)     at java.lang.StringBuffer.append(StringBuffer.java:237)     at JavaHeapTest.<init>(JavaHeapTest.java:14)     at JavaHeapTest.main(JavaHeapTest.java:34) 301989886

控制台信息可以定位到OOM发生是在JavaHeapTest第14行

1.我们用VisualVM装入堆dump文件(d:dumpjava_pid8444.hprof),文件越大,装载时间越长,点击摘要,在基本信息里找到导致OutOfMemoryError的异常线程main,查看线程的堆栈,与抛出的错误信息一致,可以定位到代码的行数。

【VisualVM 简明教程】(2):分析堆内存OOM

【VisualVM 简明教程】(2):分析堆内存OOM

【VisualVM 简明教程】(2):分析堆内存OOM

【VisualVM 简明教程】(2):分析堆内存OOM

其中at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:415) Local VARiable: java.lang.String#1 代表这里发生OOM的时候,String对象的实例号是1,点进去可以看到1的实例内容是字符串a,实例2的内容是reference Handler,这对分析以前常见的直接引用错误非常直观,有多少个实例,每个实例都是什么内容,一清二楚。面的字段引用,可以追溯到JavaHeapTest这个类的tempOOm(只能追溯全局变量) 发生的问题,可以定位到发生OOM的类,实际上可以通过1的堆栈信

2.选择类,按照类名大小排序,选择最大的char[],然后排序char[]的实例,选择最大的,查看右边的字段,展开下息,直接定位到char[]#1这个实例,造成OOM。

【VisualVM 简明教程】(2):分析堆内存OOM

【VisualVM 简明教程】(2):分析堆内存OOM

解决方案

增大堆大小,最后测试-Xmx7024m -Xms7024m 不会报OOM
共 4,291,445,456 个字节 / 900000000 = 4.7 (有一个char大约占用2个字节,可能是中间有复制拷贝吧)此方法不是根本解决方法,只是演示,根本是优化存大对象的方案。
如果用字符串相加替代Stringbuffer,相当慢,堆最高可以达到1G,之后是不断的GC,这里不做演示,有兴趣的童鞋,可以运用此方法,举一反三。

最后堆dump文件之间还可以比较差异,用于分析2个时间段堆中对象的变化,用于发现潜在的OOM。

【VisualVM 简明教程】(2):分析堆内存OOM

堆dump文件,其实就相当于一个数据库文件,VisualVm提供了OQL控制台,可以像用SQL一样,快速查出我们需要的对象信息,例如:select s From java.lang.String s where s.count > 100 查看长度大于100的字符串,这一块以后有机会单独去介绍。

参考资料


感谢您的耐心阅读,如果您发现文章中有一些没表述清楚的,或者是不对的地方,请给我留言,你的鼓励是作者写作最大的动力,
如果您认为本文质量不错,读后觉得收获很大,不妨小额赞助我一下,让我更有动力继续写出高质量的文章。

  • 支付宝

【VisualVM 简明教程】(2):分析堆内存OOM

  • 微信

【VisualVM 简明教程】(2):分析堆内存OOM

作 者 : @mousycoder

原文出处 : http://mousycoder.com/2016/01...

创作时间:2016-1-15

更新时间:2016-1-15

脚本宝典总结

以上是脚本宝典为你收集整理的【VisualVM 简明教程】(2):分析堆内存OOM全部内容,希望文章能够帮你解决【VisualVM 简明教程】(2):分析堆内存OOM所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。