jvm 生成javacore和heapdump文件
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:
输出的各列的含义。可见该命令也主要针对运行时内存。
Column | Description |
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:///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