深入JVM系列之(3):JavaCore和HeapDump

jvm 生成javacore和heapdump文件

在Server端开发与运维中,经常需要生成javacore和heapdump文件,以便分析jvm的运行状态。javacore文件中给出jvm线程的详细情况,而heapdump文件则给出jvm的运行时内存的使用情况,对分析JVM的内存泄漏有重要的作用。其中,javacore文件一般是文本文件,而heapdump则一般是二进制文件,需要使用专门的分析工具进行分析,一般常用的工具为IBM的heap anylizer。

JavaCore是关于CPU的,而HeapDump文件是关于内存的。

JavaCore文件主要保存的是Java应用各线程在某一时刻的运行的位置,即JVM执行到哪一个类、哪一个方法、哪一个行上。它是一个文本文件,打开后可以看到每一个线程的执行栈,以stack trace的显示。通过对JavaCore文件的分析可以得到应用是否“卡”在某一点上,即在某一点运行的时间太长,例如数据库查询,长期得不到响应,最终导致系统崩溃等情况。

一般JavaCore文件生成两个比较有效,可以对比这两个JavaCore文件,来对比哪个线程“卡”住了。

HeapDump文件是一个二进制文件,它保存了某一时刻JVM堆中对象使用情况,这种文件需要相应的工具进行分析,如IBM Heap Analyzer这类工具。这类文件最重要的作用就是分析系统中是否存在内存溢出的情况。

 
(1)Oracle JVM
如果使用Oracle JVM也就是标准的SUN JVM(SUN已被oracle收购)当内存溢出时生成heapdump文件配置如下
1 -Xloggc:${目录}/temp_gc.log           (GC日志文件)
2 -XX:+HeapDumpOnOutOfMemoryError       (内存溢出时生成heapdump文件)
3 -XX:HeapDumpPath=${目录}              (heapdump文件存放位置)

 


如果要即时动态生成heapdump文件可以使用jmap命令,jdk6.0已取消了-XX:+HeapDumpOnCtrlBreak配置参数通过ctrl+break的方式。
1 jmap -dump:format=b,file=temp_heapdump.hprof 

 

而javacore文件的生成,则需要依赖于kill命令,当jvm进程被杀死的时候,生成javacore文件。



(2)HP JVM
与生成heapdump相关的命令行参数:
1 -Xverbosegc:file=${目录}/temp_gc.log  (GC日志文件)
2 -XX:+HeapDumpOnOutOfMemoryError       (内存溢出时生成heapdump文件)
3 -XX:+HeapDumpOnCtrlBreak              (可以通过ctrl+break组合键动态生成heapdump文件 HP JVM也在jdk6中取消了这一方式吗??)
4 -XX:HeapDumpPath=${目录}              (heapdump文件存放位置)

 



(3)IBM JVM
非windows操作系统环境中
1 -XverboseGClog: ${目录}/temp_gc.log   (GC日志文件)
2 -Xdump:heap:events=user,file=${目录}/pid%uid%pid.phd

 表示可以根据需要通过kill -3 产生DUMP文件,%uid和%pid为变量


windows操作系统环境中:启动wsadmin,进入wsadmin环境
1 wsadmin> set jvm [$AdminControl completeObjectName type=JVM,process=server1,*]
2 wsadmin> $AdminControl invoke $jvm generateHeapDump
3 wsadmin> $AdminControl invoke $jvm dumpThreads

 

 

以上主要是通过命令行,配置使用kill命令生成javacore和heapdump文件。 

 

 

on-the-fly way

linux环境下,使用ps -ef 或者ps -aux命令,或者top命令,得到pid,然后使用kill 命令杀死特定进程,产生java core 和heap dump 文件。kill命令就是用户向进程发送signal。

那么问题来了: kill命令必须杀死进程才能获得java core和heap dump文件,能否在不杀死进程的情况下产生这两个文件呢?

实际上,jdk给我们提供了多种工具命令,这些命令保存在jdk的bin目录下,它们被称为Standard JDK Tools and Utilities基本的工具有:appletviewer, apt, extcheck, jar, java, javac, javadoc, 等等。 而用来Troubleshooting的工具主要有:jinfo, jhat, jmap, jsadebugd, jstack,jstat等等。

 

 

jmap:

jmap prints shared object memory maps or heap memory details of a given process or core file or a remote debug server. If the given process is running on a 64-bit VM, you may need to specify the -J-d64 option, e.g.:

jmap -J-d64 -heap pid



jmap输出如下:
 1 C:\Users\IBM_ADMIN>jmap -J-d64 -heap 9952
 2 Attaching to process ID 9952, please wait...
 3 Debugger attached successfully.
 4 Server compiler detected.
 5 JVM version is 25.60-b23
 6 
 7 using thread-local object allocation.
 8 Parallel GC with 4 thread(s)
 9 
10 Heap Configuration:
11    MinHeapFreeRatio         = 0
12    MaxHeapFreeRatio         = 100
13    MaxHeapSize              = 1073741824 (1024.0MB)
14    NewSize                  = 89128960 (85.0MB)
15    MaxNewSize               = 357564416 (341.0MB)
16    OldSize                  = 179306496 (171.0MB)
17    NewRatio                 = 2
18    SurvivorRatio            = 8
19    MetaspaceSize            = 21807104 (20.796875MB)
20    CompressedClassSpaceSize = 1073741824 (1024.0MB)
21    MaxMetaspaceSize         = 17592186044415 MB
22    G1HeapRegionSize         = 0 (0.0MB)
23 
24 Heap Usage:
25 PS Young Generation
26 Eden Space:
27    capacity = 348651520 (332.5MB)
28    used     = 4341152 (4.140045166015625MB)
29    free     = 344310368 (328.3599548339844MB)
30    1.245126365718985% used
31 From Space:
32    capacity = 1048576 (1.0MB)
33    used     = 0 (0.0MB)
34    free     = 1048576 (1.0MB)
35    0.0% used
36 To Space:
37    capacity = 1048576 (1.0MB)
38    used     = 0 (0.0MB)
39    free     = 1048576 (1.0MB)
40    0.0% used
41 PS Old Generation
42    capacity = 525860864 (501.5MB)
43    used     = 280628384 (267.6280822753906MB)
44    free     = 245232480 (233.87191772460938MB)
45    53.36551989539195% used
46 
47 36434 interned Strings occupying 3405440 bytes.

 

 

 

jhat:

parses a java heap dump file and launches a webserver. jhat enables you to browse heap dumps using your favorite webbrowser.

jstat:

输出的各列的含义。可见该命令也主要针对运行时内存。

ColumnDescription
S0 Survivor space 0 utilization as a percentage of the space's current capacity.
S1 Survivor space 1 utilization as a percentage of the space's current capacity.
E Eden space utilization as a percentage of the space's current capacity.
O Old space utilization as a percentage of the space's current capacity.
P Permanent space utilization as a percentage of the space's current capacity.
YGC Number of young generation GC events.
YGCT Young generation garbage collection time.
FGC Number of full GC events.
FGCT Full garbage collection time.
GCT Total garbage collection time.

 

 jstack:

jstack prints Java stack traces of Java threads for a given Java process or core file or a remote debug server.

jstack -J-d64 -m pid

-m
prints mixed mode (both Java and native C/C++ frames) stack trace.



样例输出如下:

  1 C:\Users\IBM_ADMIN>jstack -J-d64 -m 9952
  2 Attaching to process ID 9952, please wait...
  3 Debugger attached successfully.
  4 Server compiler detected.
  5 JVM version is 25.60-b23
  6 Deadlock Detection:
  7 
  8 No deadlocks found.
  9 
 10 ----------------- 0 -----------------
 11 0x00000000776e937a      USER32!WaitMessage + 0xa
 12 ----------------- 1 -----------------
 13 ----------------- 2 -----------------
 14 ----------------- 3 -----------------
 15 ----------------- 4 -----------------
 16 ----------------- 5 -----------------
 17 ----------------- 6 -----------------
 18 ----------------- 7 -----------------
 19 ----------------- 8 -----------------
 20 0x000000007793bb7a      ntdll!ZwWaitForSingleObject + 0xa
 21 ----------------- 9 -----------------
 22 0x000000007793bb7a      ntdll!ZwWaitForSingleObject + 0xa
 23 ----------------- 10 -----------------
 24 0x000000007793bb7a      ntdll!ZwWaitForSingleObject + 0xa
 25 ----------------- 11 -----------------
 26 0x000000007793bb7a      ntdll!ZwWaitForSingleObject + 0xa
 27 ----------------- 12 -----------------
 28 0x000000007793bb7a      ntdll!ZwWaitForSingleObject + 0xa
 29 ----------------- 13 -----------------
 30 0x000000007793bb7a      ntdll!ZwWaitForSingleObject + 0xa
 31 ----------------- 14 -----------------
 32 0x000000007793bb7a      ntdll!ZwWaitForSingleObject + 0xa
 33 ----------------- 15 -----------------
 34 0x000000007793bb7a      ntdll!ZwWaitForSingleObject + 0xa
 35 ----------------- 16 -----------------
 36 ----------------- 17 -----------------
 37 0x000000007793bb7a      ntdll!ZwWaitForSingleObject + 0xa
 38 ----------------- 18 -----------------
 39 0x000000007793bb7a      ntdll!ZwWaitForSingleObject + 0xa
 40 ----------------- 19 -----------------
 41 0x000000007793bb7a      ntdll!ZwWaitForSingleObject + 0xa
 42 ----------------- 20 -----------------
 43 0x000000007793bb7a      ntdll!ZwWaitForSingleObject + 0xa
 44 ----------------- 21 -----------------
 45 0x000000007793bb7a      ntdll!ZwWaitForSingleObject + 0xa
 46 ----------------- 22 -----------------
 47 0x000000007793bb7a      ntdll!ZwWaitForSingleObject + 0xa
 48 ----------------- 23 -----------------
 49 0x000000007793bb7a      ntdll!ZwWaitForSingleObject + 0xa
 50 ----------------- 24 -----------------
 51 0x000000007793c0ea      ntdll!NtWaitForMultipleObjects + 0xa
 52 ----------------- 25 -----------------
 53 0x000000007793bb7a      ntdll!ZwWaitForSingleObject + 0xa
 54 ----------------- 26 -----------------
 55 0x000000007793bb7a      ntdll!ZwWaitForSingleObject + 0xa
 56 ----------------- 27 -----------------
 57 0x000000007793bb7a      ntdll!ZwWaitForSingleObject + 0xa
 58 ----------------- 28 -----------------
 59 0x000000007793bb7a      ntdll!ZwWaitForSingleObject + 0xa
 60 ----------------- 29 -----------------
 61 0x000000007793bb7a      ntdll!ZwWaitForSingleObject + 0xa
 62 ----------------- 30 -----------------
 63 0x000000007793c0ea      ntdll!NtWaitForMultipleObjects + 0xa
 64 ----------------- 31 -----------------
 65 0x000000007793bb7a      ntdll!ZwWaitForSingleObject + 0xa
 66 ----------------- 32 -----------------
 67 0x000000007793bb7a      ntdll!ZwWaitForSingleObject + 0xa
 68 ----------------- 33 -----------------
 69 ----------------- 34 -----------------
 70 ----------------- 35 -----------------
 71 0x000000007793bb7a      ntdll!ZwWaitForSingleObject + 0xa
 72 ----------------- 36 -----------------
 73 0x000000007793bb7a      ntdll!ZwWaitForSingleObject + 0xa
 74 ----------------- 37 -----------------
 75 ----------------- 38 -----------------
 76 0x000000007793c0ea      ntdll!NtWaitForMultipleObjects + 0xa
 77 ----------------- 39 -----------------
 78 0x000000007793c0ea      ntdll!NtWaitForMultipleObjects + 0xa
 79 ----------------- 40 -----------------
 80 0x000000007793c0ea      ntdll!NtWaitForMultipleObjects + 0xa
 81 ----------------- 41 -----------------
 82 0x000000007793bb7a      ntdll!ZwWaitForSingleObject + 0xa
 83 ----------------- 42 -----------------
 84 ----------------- 43 -----------------
 85 0x000000007793c0ea      ntdll!NtWaitForMultipleObjects + 0xa
 86 ----------------- 44 -----------------
 87 ----------------- 45 -----------------
 88 0x000000007793bb7a      ntdll!ZwWaitForSingleObject + 0xa
 89 ----------------- 46 -----------------
 90 0x000000007793bb7a      ntdll!ZwWaitForSingleObject + 0xa
 91 ----------------- 47 -----------------
 92 0x000000007793bb7a      ntdll!ZwWaitForSingleObject + 0xa
 93 ----------------- 48 -----------------
 94 0x000000007793bb7a      ntdll!ZwWaitForSingleObject + 0xa
 95 ----------------- 49 -----------------
 96 ----------------- 50 -----------------
 97 0x000000007793bb7a      ntdll!ZwWaitForSingleObject + 0xa
 98 ----------------- 51 -----------------
 99 0x000000007793bb7a      ntdll!ZwWaitForSingleObject + 0xa
100 ----------------- 52 -----------------
101 0x000000007793bb7a      ntdll!ZwWaitForSingleObject + 0xa

 

基本看不懂。。。

 

结论: 要想debug一个真正的bug,还得靠详细的javacore文件和heapdump文件!

 

参考文献:

http://www.codeceo.com/article/java-javacore-heapdump.html

http://blog.itpub.net/14710393/viewspace-754416

工具集:

http://docs.oracle.com/javase/7/docs/technotes/tools/index.html#jconsole

http://docs.oracle.com/javase/7/docs/technotes/tools/share/jmap.html

http://docs.oracle.com/javase/7/docs/technotes/tools/share/jhat.html

http://docs.oracle.com/javase/7/docs/technotes/tools/share/jstat.html

http://docs.oracle.com/javase/7/docs/technotes/tools/share/jstack.html

 

posted @ 2016-06-08 21:52  Zhao_Gang  阅读(5632)  评论(0编辑  收藏  举报