1.JVM-堆快照(Snapshot)

1.1 输出方式-获取hprof文件

启动参数配置OOM时触发打印堆快照

(1)tomcat启动方式添加参数

(添加环境变量) exportJAVA_OPTS=

-XX:+HeapDumpOnOutOfMemoryError (表明进行统计相关heapDump文件再OOM的时候)

-XX:HeapDumpPath=/export/Domains/rcsv-fm.wd.local/server1/logs/gc.hprof(表明会导出生产的HeapDump文件的路径)

(2)  jvm 命令参数

(添加环境变量) Java -jar

-XX:+HeapDumpOnOutOfMemoryError (表明进行统计相关heapDump文件再OOM的时候)

-XX:HeapDumpPath=/export/Domains/rcsv-fm.wd.local/server1/logs/gc.hprof(表明会导出生产的HeapDump文件的路径)

(1)-XX:+HeapDumpOnOutOfMemoryError参数表示当JVM发生OOM时,自动生成DUMP文件。

(2)-XX:HeapDumpPath=${目录}参数表示生成DUMP文件的路径,也可以指定文件名称,例如:-XX:HeapDumpPath=${目录}/java_heapdump.hprof。如果不指定文件名,默认为:java____heapDump.hprof。

启动参数配置OOM时触发打印堆快照

jmap -dump:format=b,file=xxx.hprof  pid

jmap  -dump:format=b,file=/path/heap.bin 进程ID

如果只dump heap中的存活对象,则加上选项-live。

kill -3 or -9 都不会打堆快照,kill jvm来不及做任何事情就被干掉了,-3会打印thread dump 但是不是heap dump。

ps -ef|grep tomcat  #获取tomcat的pid/jps -lv

-XX:+PrintGCDetails -Xloggc:/opt/logs/gc.log -verbose:gc

jmap -histo:live pid>a.log

1.2 题外话相关环境变量设置参数

export TOMCAT_HOME=/tol/newapp/libclass-tomcat

export JAVA_HOME=/usr/java/jdk1.6.0_33

export JDK_HOME=/usr/java/jdk1.6.0_33

export PATH=$PATH:/usr/java/jdk1.6.0_33/bin

export CLASSPATH=/usr/java/jdk1.6.0_33/lib

export classpath=/usr/java/jdk1.6.0_33/lib

export JAVA_OPTS="-Xms4096m -Xmx4096m -XX:PermSize=256m -XX:MaxPermSize=512m  -Dfile.encoding=UTF-8 -XX:+PrintGCDetails -XX:+UseBiasedLocking  -XX:+DisableExplicitGC  -XX:+UseConcMarkSweepGC -XX:+UseParNewGC  -XX:+CMSParallelRemarkEnabled -XX:+UseCMSCompactAtFullCollection -XX:LargePageSizeInBytes=128m  -XX:+UseFastAccessorMethods -XX:+UseCMSInitiatingOccupancyOnly"

通过命令查看大对象

也是使用jmap的命令,只不过参数使用-histo

使用:jmap -histo |less

可得到如下包含对象序号、某个对象示例数、当前对象所占内存的大小、当前对象的全限定名,

查看对象数最多的对象,并按降序排序输出:

执行:jmap -histo |grep alibaba|sort -k 2 -g -r|less

查看占用内存最多的最象,并按降序排序输出:

执行:jmap -histo |grep alibaba|sort -k 3 -g -r|less

总结

1.如果程序内存不足或者频繁GC,很有可能存在内存泄露情况,这时候就要借助Java堆Dump查看对象的情况。

2.要制作堆Dump可以直接使用jvm自带的jmap命令

3.可以先使用jmap -heap命令查看堆的使用情况,看一下各个堆空间的占用情况。

4.使用jmap -histo:[live]查看堆内存中的对象的情况。如果有大量对象在持续被引用,并没有被释放掉,那就产生了内存泄露,就要结合代码,把不用的对象释放掉。

5.也可以使用 jmap -dump:format=b,file=命令将堆信息保存到一个文件中,再借助jhat命令查看详细内容

6.在内存出现泄露、溢出或者其它前提条件下,建议多dump几次内存,把内存文件进行编号归档,便于后续内存整理分析。

7.在用cms gc的情况下,执行jmap -heap有些时候会导致进程变T,因此强烈建议别执行这个命令,如果想获取内存目前每个区域的使用状况,可通过jstat -gc或jstat -gccapacity来拿到。

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐