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来拿到。