首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

(转)浅析JVM崩溃的原因及解决办法

2012-12-20 
(转)浅析JVM崩溃的原因及解决方法崩溃错误信息如下:# ?#?An?unexpected?error?has?been?detected?by?HotSp

(转)浅析JVM崩溃的原因及解决方法

崩溃错误信息如下:

  1. # ?#?An?unexpected?error?has?been?detected?by?HotSpot?Virtual?Machine: ?
  2. # ?#??EXCEPTION_ACCESS_VIOLATION?(0xc0000005)?at?pc=0x009fcf52,?pid=4752,?tid=4440?
  3. # ?#?Java?VM:?Java?HotSpot(TM)?Client?VM?(1.5.0_14-b03?mixed?mode) ?
  4. #?Problematic?frame: ?#?V??[jvm.dll+0x9cf52] ?
  5. # ?#?An?error?report?file?with?more?information?is?saved?as?hs_err_pid4752.log ?
  6. # ?#?If?you?would?like?to?submit?a?bug?report,?please?visit: ?
  7. #???http://java.sun.com/webapps/bugreport/crash.jsp ?#?

我只不过是想通过C++生成一个Java的Date对象,然后输出当前时间。通过这点错误信息我们大概可以知道的是

JVM crash了,输出错误到hs_err_pid4752.log日志。

结果运行死活都报这个错,也产生了一个log错误日志。其实运行一次产生一个,错都一样,我只举其中一个:

为了防止本机信息泄露,我把路径屏掉。

  1. # ?#?An?unexpected?error?has?been?detected?by?HotSpot?Virtual?Machine: ?
  2. # ?#??EXCEPTION_ACCESS_VIOLATION?(0xc0000005)?at?pc=0x009fcf52,?pid=4344,?tid=5876?
  3. # ?#?Java?VM:?Java?HotSpot(TM)?Client?VM?(1.5.0_14-b03?mixed?mode) ?
  4. #?Problematic?frame: ?#?V??[jvm.dll+0x9cf52] ?
  5. # ??
  6. ---------------??T?H?R?E?A?D??--------------- ??
  7. Current?thread?(0x00823d30):??JavaThread?"main"?[_thread_in_vm,?id=5876] ??
  8. siginfo:?ExceptionCode=0xc0000005,?reading?address?0x00000000 ??
  9. Registers: ?EAX=0x00000000,?EBX=0x06f8c0f8,?ECX=0x0006f954,?EDX=0x00823df0?
  10. ESP=0x0006f934,?EBP=0x0006f980,?ESI=0x0006f954,?EDI=0x0006f9e8?EIP=0x009fcf52,?EFLAGS=0x00010246?
  11. ?Top?of?Stack:?(sp=0x0006f934) ?
  12. 0x0006f934:???009eb893?00000000?00823d30?009ecac3 ?0x0006f944:???00823d30?00000000?0006f9fc?0006f998 ?
  13. 0x0006f954:???00823df0?0082b438?009a1e20?00823d30 ?0x0006f964:???0006f980?009ebb6a?00823d30?0000000e ?
  14. 0x0006f974:???00000004?0006f9e8?0006f998?0006f9e8 ?0x0006f984:???1000148b?00823df0?0082b434?00000000 ?
  15. 0x0006f994:???0006f9fc?0006fa5c?06f8c0f8?06f8c0f8 ?0x0006f9a4:???cccccccc?cccccccc?cccccccc?cccccccc? ?
  16. ?Instructions:?(pc=0x009fcf52) ?
  17. 0x009fcf42:???44?24?04?24?fc?8b?00?8b?00?c3?8b?44?24?04?24?fc ?0x009fcf52:???8b?00?ff?74?24?04?8b?c8?e8?93?fe?ff?ff?c3?8b?44? ?
  18. ??
  19. Stack:?[0x00030000,0x00070000),??sp=0x0006f934,??free?space=254k?Native?frames:?(J=compiled?Java?code,?j=interpreted,?Vv=VM?code,?C=native?code) ?
  20. V??[jvm.dll+0x9cf52] ?C??[NativeCode.dll+0x148b] ?
  21. C??[NativeCode.dll+0x1253] ?j??com.sy.test.TestNative.sayHello()V+0 ?
  22. j??com.sy.test.TestNative.main([Ljava/lang/String;)V+22 ?v??~StubRoutines::call_stub ?
  23. V??[jvm.dll+0x875dd] ?V??[jvm.dll+0xdfd96] ?
  24. V??[jvm.dll+0x874ae] ?V??[jvm.dll+0x8e6f1] ?
  25. C??[javaw.exe+0x14c5] ?C??[javaw.exe+0x3151] ?
  26. C??[kernel32.dll+0x16fd7] ??
  27. Java?frames:?(J=compiled?Java?code,?j=interpreted,?Vv=VM?code) ?j??com.sy.test.TestNative.sayHello()V+0 ?
  28. j??com.sy.test.TestNative.main([Ljava/lang/String;)V+22 ?v??~StubRoutines::call_stub ?
  29. ?---------------??P?R?O?C?E?S?S??--------------- ?
  30. ?Java?Threads:?(?=>?current?thread?) ?
  31. ??0x008306d0?JavaThread?"Low?Memory?Detector"?daemon?[_thread_blocked,?id=5624] ???0x0082fb30?JavaThread?"CompilerThread0"?daemon?[_thread_blocked,?id=5988] ?
  32. ??0x0082e8c0?JavaThread?"Signal?Dispatcher"?daemon?[_thread_blocked,?id=2400] ???0x0082de70?JavaThread?"Finalizer"?daemon?[_thread_blocked,?id=5704] ?
  33. ??0x0082ccf0?JavaThread?"Reference?Handler"?daemon?[_thread_blocked,?id=4240] ?=>0x00823d30?JavaThread?"main"?[_thread_in_vm,?id=5876] ?
  34. ?Other?Threads: ?
  35. ??0x0082a060?VMThread?[id=1960] ???0x00831270?WatcherThread?[id=5708] ?
  36. ?VM?state:not?at?safepoint?(normal?execution) ?
  37. ?VM?Mutex/Monitor?currently?owned?by?a?thread:?None ?
  38. ?Heap ?
  39. ?def?new?generation???total?576K,?used?209K?[0x02de0000,?0x02e80000,?0x032c0000) ???eden?space?512K,??40%?used?[0x02de0000,?0x02e14510,?0x02e60000) ?
  40. ??from?space?64K,???0%?used?[0x02e60000,?0x02e60000,?0x02e70000) ???to???space?64K,???0%?used?[0x02e70000,?0x02e70000,?0x02e80000) ?
  41. ?tenured?generation???total?1408K,?used?0K?[0x032c0000,?0x03420000,?0x06de0000) ????the?space?1408K,???0%?used?[0x032c0000,?0x032c0000,?0x032c0200,?0x03420000) ?
  42. ?compacting?perm?gen??total?8192K,?used?1715K?[0x06de0000,?0x075e0000,?0x0ade0000) ????the?space?8192K,??20%?used?[0x06de0000,?0x06f8cdb0,?0x06f8ce00,?0x075e0000) ?
  43. No?shared?spaces?configured. ??
  44. Dynamic?libraries: ?0x00400000?-?0x0040d000??******************************* ?
  45. ?0x7c920000?-?0x7c9b4000??C:\WINDOWS\system32\ntdll.dll ?
  46. 0x7c800000?-?0x7c91d000??C:\WINDOWS\system32\kernel32.dll ?0x77da0000?-?0x77e49000??C:\WINDOWS\system32\ADVAPI32.dll ?
  47. 0x77e50000?-?0x77ee2000??C:\WINDOWS\system32\RPCRT4.dll ?0x77fc0000?-?0x77fd1000??C:\WINDOWS\system32\Secur32.dll ?
  48. 0x77d10000?-?0x77d9f000??C:\WINDOWS\system32\USER32.dll ?0x77ef0000?-?0x77f38000??C:\WINDOWS\system32\GDI32.dll ?
  49. 0x77be0000?-?0x77c38000??C:\WINDOWS\system32\MSVCRT.dll ?0x76300000?-?0x7631d000??C:\WINDOWS\system32\IMM32.DLL ?
  50. 0x62c20000?-?0x62c29000??C:\WINDOWS\system32\LPK.DLL ?0x73fa0000?-?0x7400b000??C:\WINDOWS\system32\USP10.dll ?
  51. 0x6d710000?-?0x6d723000??C:\PROGRA~1\KASPER~1\KASPER~1\mzvkbd.dll ?0x76bc0000?-?0x76bcb000??C:\WINDOWS\system32\PSAPI.DLL ?
  52. 0x6d730000?-?0x6d743000??C:\PROGRA~1\KASPER~1\KASPER~1\mzvkbd3.dll ?0x6d020000?-?0x6d035000??C:\PROGRA~1\KASPER~1\KASPER~1\adialhk.dll ?
  53. 0x77f40000?-?0x77fb6000??C:\WINDOWS\system32\SHLWAPI.dll ?0x6d4c0000?-?0x6d4c6000??C:\PROGRA~1\KASPER~1\KASPER~1\kloehk.dll ?
  54. 0x00960000?-?0x00afe000??******************************* ??
  55. 0x76b10000?-?0x76b3a000??C:\WINDOWS\system32\WINMM.dll ?0x6d290000?-?0x6d298000?******************************* ?
  56. ?0x6d610000?-?0x6d61c000??******************************* ?
  57. ?0x6d310000?-?0x6d32d000?******************************* ?
  58. ?0x6d630000?-?0x6d63f000??******************************* ?
  59. ?0x10000000?-?0x1004e000??******************************* ?
  60. ?VM?Arguments: ?
  61. java_command:?com.sy.test.TestNative ?Launcher?Type:?SUN_STANDARD ?
  62. ?Environment?Variables: ?
  63. JAVA_HOME=******************************* ??
  64. CLASSPATH=******************************* ?PATH=******************************* ?
  65. USERNAME=user?OS=Windows_NT?
  66. PROCESSOR_IDENTIFIER=x86?Family?6?Model?14?Stepping?8,?GenuineIntel ??
  67. ??
  68. ---------------??S?Y?S?T?E?M??--------------- ??
  69. OS:?Windows?XP?Build?2600?Service?Pack?2 ??
  70. CPU:total?1?(cores?per?cpu?1,?threads?per?core?1)?family?6?model?14?stepping?8,?cmov,?cx8,?fxsr,?mmx,?sse,?sse2 ??
  71. Memory:?4k?page,?physical?1300464k(465904k?free),?swap?3092560k(2157304k?free) ??
  72. vm_info:?Java?HotSpot(TM)?Client?VM?(1.5.0_14-b03)?for?windows-x86,?built?on?Oct??5?2007?01:21:52?by?"java_re"?with?MS?VC++?6.0?

看到就些错误日志就可以断定是由于我用Java的主函数调用本地dll文件时出了错。

我初步推断是因为我的C++产生Java对象传给Java类后,没有回收。导致内存泄露。

?

Java的应用有时候会因为各种原因Crash,这时候会产生一个类似java_errorpid.log的错误日志。可以拿到了

这个日志,怎样分析Crash的原因呢?下面我们来详细讨论如何分析java_errorpid.log的错误日志。

一. 如何得到这个日志文件

如果有一个严重的错误引起Java进程非正常退出,我们叫Crash,这时候会产生一个日志文件。缺省情况下,这个

文件会产生在工作目录下。但是,可以在Java启动参数通过下面的设置,来改变这个文件的位置和命名规则。例如:

java -XX:ErrorFile=/var/log/java/java_error_%p.log

就将这个错误文件放在/var/log/java下,并且以java_error_pid.log的形式出现。

二.产生错误的原因

造成严重错误的原因有多种可能性。Java虚拟机自身的Bug是原因之一,但是这种可能不是很大。在绝大多数情况下,是由于系统的库文件、API或第三方的库文件造成的;系统资源的短缺也有可能造成这种严重的错误。在发生了Crash之后,如果无法定位根本原因,也应该迅速找到Work Around的方法。

三.对日志文件的分析

首先要检查日志的文件头:例如,下面是从一个客户发过来的错误日志的文件头

  1. ------------------------------------- ?# ?
  2. #?An?unexpected?error?has?been?detected?by?HotSpot?Virtual?Machine: ?# ?
  3. #?EXCEPTION_ACCESS_VIOLATION?(0xc0000005)?at?pc=0x0815e87e,?pid=7268,?tid=4360?# ?
  4. #?Java?VM:?Java?HotSpot(TM)?Server?VM?(1.4.2_13-b06?mixed?mode) ?#?Problematic?frame: ?
  5. #?V?[jvm.dll+0x15e87e] ?# ?
  6. --------------------------------------?

文件头中有很多有用的信息,“EXCEPTION_ACCESS_VIOLATION ”意味着Java应用Crash的时候,正在运行JVM自己的代码,而不是外部的Java代码或其他类库代码。这种情况很可能是JVM的Bug,但是也不一定。除了“EXCEPTION_ACCESS_VIOLATION ”,还有可能是别的信息,例如“SIGSEGV(0xb)”,意味着JVM正在执行本地或JNI的代码;“EXCEPTION_STACK_OVERFLOW”意味着这是个栈溢出的错误。(**********看到这里我们知道我报错时正在运行JVM自己的代码,而不是外部的Java代码或其他类库代码*********)

另外一个有用的JVM崩溃信息就是:

  1. #?Problematic?frame: ?#?V?[jvm.dll+0x15e87e]?

它说明Crash的时候,JVM正在从哪个库文件执行代码。除了“V”以外,还有可能是“C”、“j”、“v”、“J”。具体的表示意思如下:

  1. FrameType?Description: ?C:?Native?C?frame ?
  2. j:?Interpreted?Java?frame ?V:?VMframe ?
  3. v:?VMgenerated?stub?frame ?J:?Other?frame?types,?including?compiled?Java?frames ?
  4. ?(**********看到这里我们知道我报错时是V:?VMframe这种情况*********)?

文件头之后,是当前线程的DUMP信息,线程之后是JVM进程的DUMP信息,包括所有线程的状态、地址和ID。最后还有JVM状态,

Heap状态,动态连接库等等的信息。这些烦乱的信息中,包含有非常有用的信息。下面我们根据几个具体的实例来分析JVM崩溃的典型例子。

四.内存回收引起的Crash

内存回收引起的Crash有以下的特点:在日志文件头一般有“ EXCEPTION_ACCESS _VIOLATION”和

“# Problematic frame: # V [jvm.dll+....”的信息,意味着这是在JVM内部处理,而且多半是JVM的Bug。

(**********看到这里我们知道我报错时意味着这是在JVM内部处理,而且多半是JVM的Bug*********)

对于这类问题,最快的方法就是绕过它。

另外,在Thread的DUMP信息最后,还能看到有关内存回收的行为例如:

  1. ---------------?T?H?R?E?A?D?--------------- ?Current?thread?(0x00a56668):?VMThread?[id=4360] ?
  2. siginfo:?ExceptionCode=0xc0000005,?reading?address?0x00000057 ?Registers: ?
  3. ........ ??
  4. Stack:?[0x03cf0000,0x03d30000),?sp=0x03d2fc18,?free?space=255k?Native?frames:?(J=compiled?Java?code,?j=interpreted,?Vv=VM?code,?C=native?code) ?
  5. V?[jvm.dll+0x15e87e] ??
  6. VM_Operation?(0x063efbac):?full?generation?collection,?mode:?safepoint,?requested?by?thread?0x040f83f8 ?------------------------?

可以清楚的看到JVM正在做 “full generation collection”。另外还有可能看到,其他的回收行为:

对于内存回收的错误,一般

  1. generation?collection?for?allocation ?full?generation?collection ?
  2. parallel?gc?failed?allocation ?parallel?gc?failed?permanent?allocation ?
  3. parallel?gc?system?gc ?(***********这些错,俺都没碰到***********)?

采取改变回收的算法和参数的方法来绕过去。例如,来自客户的日志除了上面的日志信息,在日志中Heap信息中还能发现一些其他信息:

  1. -------------------------- ?Heap ?
  2. def?new?generation?total?22592K,?used?19530K?[0x10010000,?0x11890000,?0x138f0000) ?eden?space?20096K,?97%?used?[0x10010000,?0x11322bd8,?0x113b0000) ?
  3. from?space?2496K,?0%?used?[0x113b0000,?0x113b0000,?0x11620000) ?to?space?2496K,?0%?used?[0x11620000,?0x11620000,?0x11890000) ?
  4. tenured?generation?total?190696K,?used?100019K?[0x138f0000,?0x1f32a000,?0x30010000) ?the?space?190696K,?52%?used?[0x138f0000,?0x19a9cf38,?0x19a9d000,?0x1f32a000) ?
  5. compacting?perm?gen?total?38656K,?used?38588K?[0x30010000,?0x325d0000,?0x34010000) ?the?space?38656K,?99%?used?[0x30010000,?0x325bf038,?0x325bf200,?0x325d0000) ?
  6. ----------------------------?

上面的信息能看出在Crash的时候,JVM的PermSize空间几乎已经消耗完了,并且回收算法在压缩Perm空间的时候出了错。因此,建议改变内存回收的算法,或扩大PermSize和MaxPermSize的数值。

(*******这个倒是可以尝试*******)

五.栈溢出引起的Crash

Java代码引起的栈溢出,通常不会引起JVM的Crash,而是抛出一个Java异常:java.lang.StackOverflowError。但是在Java虚拟机中,Java的代码和本地C或C++代码公用相同的Stack。这样,在执行本地代码所造成的栈溢出,就有可能引起JVM的Crash了。栈溢出引起的Crash会在日志的文件头中看到“EXCEPTION_STACK_OVERFLOW”字样。另外,在当前线程的Stack信息中也能发现一些信息。例如下面的例子:

  1. ----------------------------------------------- ?#?An?unexpected?error?has?been?detected?by?HotSpot?Virtual?Machine: ?
  2. # ?#?EXCEPTION_STACK_OVERFLOW?(0xc00000fd)?at?pc=0x10001011,?pid=296,?tid=2940?
  3. # ?#?Java?VM:?Java?HotSpot(TM)?Client?VM?(1.6-internal?mixed?mode,?sharing) ?
  4. #?Problematic?frame: ?#?C?[App.dll+0x1011] ?
  5. # ?---------------?T?H?R?E?A?D?--------------- ?
  6. Current?thread?(0x000367c0):?JavaThread?"main"?[_thread_in_native,?id=2940] ?: ?
  7. Stack:?[0x00040000,0x00080000),?sp=0x00041000,?free?space=4k?Native?frames:?(J=compiled?Java?code,?j=interpreted,?Vv=VM?code,?C=native?code) ?
  8. C?[App.dll+0x1011] ?C?[App.dll+0x1020] ?
  9. C?[App.dll+0x1020] ?: ?
  10. C?[App.dll+0x1020] ?C?[App.dll+0x1020] ?
  11. ...... ?Java?frames:?(J=compiled?Java?code,?j=interpreted,?Vv=VM?code) ?
  12. j?Test.foo()V+0 ?j?Test.main([Ljava/lang/String;)V+0 ?
  13. v?~StubRoutines::call_stub ??
  14. --------------------------------------------?

在上面的信息中,可以发现这是个栈溢出的错误。并且当前栈剩余的空间已经很小了(free space =4k)。

因此建议将JVM的Stack的尺寸调大,主要设计两个参数:“-Xss” 和“-XX:StackShadowPages=n”。但是,将栈的尺寸调大,也意味着在有限的内存资源中,能打开的最大线程数会减少。(******俺的栈剩余还有free space=254k,显然不符,于是乎我决定假期再解决,o(∩_∩)o...******)

JVM崩溃的原因及解决方法结论:

我觉得还是C++建立Java对象后,没有回收。鉴定完毕

热点排行