﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-光子CI之旅-文章分类-JVM</title><link>http://www.blogjava.net/kuuyee/category/49223.html</link><description>while (产品+需求+设计+开发+测试 == doing) 
{ 
  CI 
}</description><language>zh-cn</language><lastBuildDate>Tue, 26 Jul 2011 02:36:48 GMT</lastBuildDate><pubDate>Tue, 26 Jul 2011 02:36:48 GMT</pubDate><ttl>60</ttl><item><title>(转)JVM崩溃的原因及解决！</title><link>http://www.blogjava.net/kuuyee/articles/355030.html</link><dc:creator>kuuyee</dc:creator><author>kuuyee</author><pubDate>Tue, 26 Jul 2011 01:49:00 GMT</pubDate><guid>http://www.blogjava.net/kuuyee/articles/355030.html</guid><wfw:comment>http://www.blogjava.net/kuuyee/comments/355030.html</wfw:comment><comments>http://www.blogjava.net/kuuyee/articles/355030.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/kuuyee/comments/commentRss/355030.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/kuuyee/services/trackbacks/355030.html</trackback:ping><description><![CDATA[原文:<a href="http://www.cnblogs.com/shiyangxt/archive/2009/01/06/1370627.html">http://www.cnblogs.com/shiyangxt/archive/2009/01/06/1370627.html</a><br /><br /><div><div id="cnblogs_post_body"><p>前些天，搞JNI的时候，报了个JVM崩溃的错。错误信息如下：</p> <p>#<br /> # An unexpected error has been detected by HotSpot Virtual Machine:<br /> #<br /> #&nbsp; EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x009fcf52, pid=4752, tid=4440<br /> #<br /> # Java VM: Java HotSpot(TM) Client VM (1.5.0_14-b03 mixed mode)<br /> # Problematic frame:<br /> # V&nbsp; [jvm.dll+0x9cf52]<br /> #<br /> # An error report file with more information is saved as hs_err_pid4752.log<br /> #<br /> # If you would like to submit a bug report, please visit:<br /> #&nbsp;&nbsp; <a href="http://java.sun.com/webapps/bugreport/crash.jsp">http://java.sun.com/webapps/bugreport/crash.jsp</a><br /> #<br /> 我只不过是想通过C++生成一个Java的Date对象，然后输出当前时间。通过这点错误信息我们大概可以知道的是</p> <p>JVM crash了，输出错误到hs_err_pid4752.log日志。</p> <p>----------------------------------------------------------------------------------------------------</p> <p>结果运行死活都报这个错，也产生了一个log错误日志。其实运行一次产生一个，错都一样，我只举其中一个：</p> <p>为了防止本机信息泄露，我把路径屏掉。</p> <p>#<br /> # An unexpected error has been detected by HotSpot Virtual Machine:<br /> #<br /> #&nbsp; EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x009fcf52, pid=4344, tid=5876<br /> #<br /> # Java VM: Java HotSpot(TM) Client VM (1.5.0_14-b03 mixed mode)<br /> # Problematic frame:<br /> # V&nbsp; [jvm.dll+0x9cf52]<br /> #</p> <p>---------------&nbsp; T H R E A D&nbsp; ---------------</p> <p>Current thread (0x00823d30):&nbsp; JavaThread "main" [_thread_in_vm, id=5876]</p> <p>siginfo: ExceptionCode=0xc0000005, reading address 0x00000000</p> <p>Registers:<br /> EAX=0x00000000, EBX=0x06f8c0f8, ECX=0x0006f954, EDX=0x00823df0<br /> ESP=0x0006f934, EBP=0x0006f980, ESI=0x0006f954, EDI=0x0006f9e8<br /> EIP=0x009fcf52, EFLAGS=0x00010246</p> <p>Top of Stack: (sp=0x0006f934)<br /> 0x0006f934:&nbsp;&nbsp; 009eb893 00000000 00823d30 009ecac3<br /> 0x0006f944:&nbsp;&nbsp; 00823d30 00000000 0006f9fc 0006f998<br /> 0x0006f954:&nbsp;&nbsp; 00823df0 0082b438 009a1e20 00823d30<br /> 0x0006f964:&nbsp;&nbsp; 0006f980 009ebb6a 00823d30 0000000e<br /> 0x0006f974:&nbsp;&nbsp; 00000004 0006f9e8 0006f998 0006f9e8<br /> 0x0006f984:&nbsp;&nbsp; 1000148b 00823df0 0082b434 00000000<br /> 0x0006f994:&nbsp;&nbsp; 0006f9fc 0006fa5c 06f8c0f8 06f8c0f8<br /> 0x0006f9a4:&nbsp;&nbsp; cccccccc cccccccc cccccccc cccccccc </p> <p>Instructions: (pc=0x009fcf52)<br /> 0x009fcf42:&nbsp;&nbsp; 44 24 04 24 fc 8b 00 8b 00 c3 8b 44 24 04 24 fc<br /> 0x009fcf52:&nbsp;&nbsp; 8b 00 ff 74 24 04 8b c8 e8 93 fe ff ff c3 8b 44 </p> <p><br /> Stack: [0x00030000,0x00070000),&nbsp; sp=0x0006f934,&nbsp; free space=254k<br /> Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)<br /> V&nbsp; [jvm.dll+0x9cf52]<br /> C&nbsp; [NativeCode.dll+0x148b]<br /> C&nbsp; [NativeCode.dll+0x1253]<br /> j&nbsp; com.sy.test.TestNative.sayHello()V+0<br /> j&nbsp; com.sy.test.TestNative.main([Ljava/lang/String;)V+22<br /> v&nbsp; ~StubRoutines::call_stub<br /> V&nbsp; [jvm.dll+0x875dd]<br /> V&nbsp; [jvm.dll+0xdfd96]<br /> V&nbsp; [jvm.dll+0x874ae]<br /> V&nbsp; [jvm.dll+0x8e6f1]<br /> C&nbsp; [javaw.exe+0x14c5]<br /> C&nbsp; [javaw.exe+0x3151]<br /> C&nbsp; [kernel32.dll+0x16fd7]</p> <p>Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)<br /> j&nbsp; com.sy.test.TestNative.sayHello()V+0<br /> j&nbsp; com.sy.test.TestNative.main([Ljava/lang/String;)V+22<br /> v&nbsp; ~StubRoutines::call_stub</p> <p>---------------&nbsp; P R O C E S S&nbsp; ---------------</p> <p>Java Threads: ( =&gt; current thread )<br /> &nbsp; 0x008306d0 JavaThread "Low Memory Detector" daemon [_thread_blocked, id=5624]<br /> &nbsp; 0x0082fb30 JavaThread "CompilerThread0" daemon [_thread_blocked, id=5988]<br /> &nbsp; 0x0082e8c0 JavaThread "Signal Dispatcher" daemon [_thread_blocked, id=2400]<br /> &nbsp; 0x0082de70 JavaThread "Finalizer" daemon [_thread_blocked, id=5704]<br /> &nbsp; 0x0082ccf0 JavaThread "Reference Handler" daemon [_thread_blocked, id=4240]<br /> =&gt;0x00823d30 JavaThread "main" [_thread_in_vm, id=5876]</p> <p>Other Threads:<br /> &nbsp; 0x0082a060 VMThread [id=1960]<br /> &nbsp; 0x00831270 WatcherThread [id=5708]</p> <p>VM state:not at safepoint (normal execution)</p> <p>VM Mutex/Monitor currently owned by a thread: None</p> <p>Heap<br /> &nbsp;def new generation&nbsp;&nbsp; total 576K, used 209K [0x02de0000, 0x02e80000, 0x032c0000)<br /> &nbsp; eden space 512K,&nbsp; 40% used [0x02de0000, 0x02e14510, 0x02e60000)<br /> &nbsp; from space 64K,&nbsp;&nbsp; 0% used [0x02e60000, 0x02e60000, 0x02e70000)<br /> &nbsp; to&nbsp;&nbsp; space 64K,&nbsp;&nbsp; 0% used [0x02e70000, 0x02e70000, 0x02e80000)<br /> &nbsp;tenured generation&nbsp;&nbsp; total 1408K, used 0K [0x032c0000, 0x03420000, 0x06de0000)<br /> &nbsp;&nbsp; the space 1408K,&nbsp;&nbsp; 0% used [0x032c0000, 0x032c0000, 0x032c0200, 0x03420000)<br /> &nbsp;compacting perm gen&nbsp; total 8192K, used 1715K [0x06de0000, 0x075e0000, 0x0ade0000)<br /> &nbsp;&nbsp; the space 8192K,&nbsp; 20% used [0x06de0000, 0x06f8cdb0, 0x06f8ce00, 0x075e0000)<br /> No shared spaces configured.</p> <p>Dynamic libraries:<br /> 0x00400000 - 0x0040d000&nbsp;&nbsp;*******************************</p> <p>0x7c920000 - 0x7c9b4000 &nbsp;C:\WINDOWS\system32\ntdll.dll<br /> 0x7c800000 - 0x7c91d000 &nbsp;C:\WINDOWS\system32\kernel32.dll<br /> 0x77da0000 - 0x77e49000 &nbsp;C:\WINDOWS\system32\ADVAPI32.dll<br /> 0x77e50000 - 0x77ee2000 &nbsp;C:\WINDOWS\system32\RPCRT4.dll<br /> 0x77fc0000 - 0x77fd1000 &nbsp;C:\WINDOWS\system32\Secur32.dll<br /> 0x77d10000 - 0x77d9f000 &nbsp;C:\WINDOWS\system32\USER32.dll<br /> 0x77ef0000 - 0x77f38000 &nbsp;C:\WINDOWS\system32\GDI32.dll<br /> 0x77be0000 - 0x77c38000 &nbsp;C:\WINDOWS\system32\MSVCRT.dll<br /> 0x76300000 - 0x7631d000 &nbsp;C:\WINDOWS\system32\IMM32.DLL<br /> 0x62c20000 - 0x62c29000 &nbsp;C:\WINDOWS\system32\LPK.DLL<br /> 0x73fa0000 - 0x7400b000 &nbsp;C:\WINDOWS\system32\USP10.dll<br /> 0x6d710000 - 0x6d723000 &nbsp;C:\PROGRA~1\KASPER~1\KASPER~1\mzvkbd.dll<br /> 0x76bc0000 - 0x76bcb000 &nbsp;C:\WINDOWS\system32\PSAPI.DLL<br /> 0x6d730000 - 0x6d743000 &nbsp;C:\PROGRA~1\KASPER~1\KASPER~1\mzvkbd3.dll<br /> 0x6d020000 - 0x6d035000 &nbsp;C:\PROGRA~1\KASPER~1\KASPER~1\adialhk.dll<br /> 0x77f40000 - 0x77fb6000 &nbsp;C:\WINDOWS\system32\SHLWAPI.dll<br /> 0x6d4c0000 - 0x6d4c6000 &nbsp;C:\PROGRA~1\KASPER~1\KASPER~1\kloehk.dll<br /> 0x00960000 - 0x00afe000&nbsp;&nbsp;*******************************</p> <p>0x76b10000 - 0x76b3a000 &nbsp;C:\WINDOWS\system32\WINMM.dll<br /> 0x6d290000 - 0x6d298000 *******************************</p> <p>0x6d610000 - 0x6d61c000&nbsp;&nbsp;*******************************</p> <p>0x6d310000 - 0x6d32d000 *******************************</p> <p>0x6d630000 - 0x6d63f000&nbsp;&nbsp;*******************************</p> <p>0x10000000 - 0x1004e000&nbsp;&nbsp;*******************************</p> <p>VM Arguments:<br /> java_command: com.sy.test.TestNative<br /> Launcher Type: SUN_STANDARD</p> <p>Environment Variables:<br /> JAVA_HOME=*******************************</p> <p>CLASSPATH=*******************************<br /> PATH=*******************************<br /> USERNAME=user<br /> OS=Windows_NT<br /> PROCESSOR_IDENTIFIER=x86 Family 6 Model 14 Stepping 8, GenuineIntel</p> <p>&nbsp;</p> <p>---------------&nbsp; S Y S T E M&nbsp; ---------------</p> <p>OS: Windows XP Build 2600 Service Pack 2</p> <p>CPU:total 1 (cores per cpu 1, threads per core 1) family 6 model 14 stepping 8, cmov, cx8, fxsr, mmx, sse, sse2</p> <p>Memory: 4k page, physical 1300464k(465904k free), swap 3092560k(2157304k free)</p> <p>vm_info: Java HotSpot(TM) Client VM (1.5.0_14-b03) for windows-x86, built on Oct&nbsp; 5 2007 01:21:52 by "java_re" with MS VC++ 6.0</p> <p>看到就些错误日志就可以断定是由于我用Java的主函数调用本地dll文件时出了错。</p> <p>我初步推断是因为我的C++产生Java对象传给Java类后，没有回收。导致内存泄露。</p> <p>但是因为我是初学者，所以对C++控制Java还不熟，所以经过调试，C++编译通不过。由于最近考试压力</p> <p>实在太大，迫使我先暂且放下这个问题。</p> <p>但是不解决心里不爽，于是开始了搜索》》》》》》》》》》》》》》》漫长的信息检索》》》》》》》</p> <p>发现新大陆》》》》》》》》》</p> <p>以下内容，转载自<a href="http://developers.sun.com.cn/blog/yutoujava/">http://developers.sun.com.cn/blog/yutoujava/</a></p> <p>-----------------------------------------------------------------------------------------------------</p> <p>Java的应用有时候会因为各种原因Crash，这时候会产生一个类似java_errorpid.log的错误日志。可以拿到了</p> <p>这个日志，怎样分析Crash的原因呢？下面我们来详细讨论如何分析java_errorpid.log的错误日志。</p> <p>一. 如何得到这个日志文件<br /> 如果有一个严重的错误引起Java进程非正常退出，我们叫Crash，这时候会产生一个日志文件。缺省情况下，这个</p> <p>文件会产生在工作目录下。但是，可以在Java启动参数通过下面的设置，来改变这个文件的位置和命名规则。例如：<br /> java -XX:ErrorFile=/var/log/java/java_error_%p.log<br /> 就将这个错误文件放在/var/log/java下，并且以java_error_pid.log的形式出现。</p> <p>&nbsp;</p> <p>二.产生错误的原因<br /> 造成严重错误的原因有多种可能性。Java虚拟机自身的Bug是原因之一，但是这种可能不是很大。在绝大多数情况下，</p> <p>是由于系统的库文件、API或第三方的库文件造成的；系统资源的短缺也有可能造成这种严重的错误。在发生了Crash</p> <p>之后，如果无法定位根本原因，也应该迅速找到Work Around的方法。</p> <p>三.对日志文件的分析<br /> 首先要检查日志的文件头：例如，下面是从一个客户发过来的错误日志的文件头</p> <p>－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－<br /> #<br /> # An unexpected error has been detected by HotSpot Virtual Machine:<br /> #<br /> # EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x0815e87e, pid=7268, tid=4360<br /> #<br /> # Java VM: Java HotSpot(TM) Server VM (1.4.2_13-b06 mixed mode)<br /> # Problematic frame:<br /> # V [jvm.dll+0x15e87e]<br /> #<br /> －－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－</p> <p>&nbsp;</p> <p>文件头中有很多有用的信息，&#8220;EXCEPTION_ACCESS_VIOLATION &#8221;意味着Java应用Crash的时候，</p> <p>正在运行JVM自己的代码，而不是外部的Java代码或其他类库代码。这种情况很可能是JVM的Bug，但是</p> <p>也不一定。除了&#8220;EXCEPTION_ACCESS_VIOLATION &#8221;，还有可能是别的信息，例如&#8220;SIGSEGV(0xb)&#8221;，</p> <p>意味着JVM正在执行本地或JNI的代码;&#8220;EXCEPTION_STACK_OVERFLOW&#8221;意味着这是个栈溢出的错误。</p> <p>&nbsp;（**********看到这里我们知道我报错时正在运行JVM自己的代码，而不是外部的Java代码或其他类库代码*********）</p> <p>另外一个有用的信息就是：<br /> # Problematic frame:<br /> # V [jvm.dll+0x15e87e]</p> <p><br /> 它说明Crash的时候，JVM正在从哪个库文件执行代码。除了&#8220;V&#8221;以外，还有可能是&#8220;C&#8221;、&#8220;j&#8221;、&#8220;v&#8221;、&#8220;J&#8221;。具体的表示意思如下：</p> <p>FrameType Description：<br /> C: Native C frame<br /> j: Interpreted Java frame<br /> V: VMframe<br /> v: VMgenerated stub frame<br /> J: Other frame types, including compiled Java frames</p> <p>（**********看到这里我们知道我报错时是V: VMframe这种情况*********）</p> <p><br /> 文件头之后，是当前线程的DUMP信息，线程之后是JVM进程的DUMP信息，包括所有线程的状态、地址和ID。最后还有JVM状态，</p> <p>Heap状态，动态连接库等等的信息。这些烦乱的信息中，包含有非常有用的信息。下面我们根据几个具体的实例来分析Java虚拟</p> <p>机Crash的典型例子。</p> <p>四.内存回收引起的Crash<br /> 内存回收引起的Crash有以下的特点：在日志文件头一般有&#8220; EXCEPTION_ACCESS _VIOLATION&#8221;和</p> <p>&#8220;# Problematic frame: # V [jvm.dll+....&#8221;的信息，意味着这是在JVM内部处理，而且多半是JVM的Bug。</p> <p>（**********看到这里我们知道我报错时意味着这是在JVM内部处理，而且多半是JVM的Bug*********）</p> <p>对于这类问题，最快的方法就是绕过它。</p> <p>另外，在Thread的DUMP信息最后，还能看到有关内存回收的行为例如：</p> <p>--------------- T H R E A D ---------------<br /> Current thread (0x00a56668): VMThread [id=4360]<br /> siginfo: ExceptionCode=0xc0000005, reading address 0x00000057<br /> Registers:<br /> ........</p> <p>Stack: [0x03cf0000,0x03d30000), sp=0x03d2fc18, free space=255k<br /> Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)<br /> V [jvm.dll+0x15e87e]</p> <p>VM_Operation (0x063efbac): full generation collection, mode: safepoint, requested by thread 0x040f83f8<br /> ------------------------------------------------------------</p> <p>可以清楚的看到JVM正在做 &#8220;full generation collection&#8221;。另外还有可能看到，其他的回收行为：</p> <p>generation collection for allocation</p> <p>full generation collection</p> <p>parallel gc failed allocation</p> <p>parallel gc failed permanent allocation</p> <p>parallel gc system gc</p> <p>（***********这些错，俺都没碰到***********）<br /> 对于内存回收的错误，一般采取改变回收的算法和参数的方法来绕过去。例如，来自客户的日志除了上面的</p> <p>日志信息，在日志中Heap信息中还能发现一些其他信息：</p> <p>--------------------------------------------------------------<br /> Heap<br /> def new generation total 22592K, used 19530K [0x10010000, 0x11890000, 0x138f0000)<br /> eden space 20096K, 97% used [0x10010000, 0x11322bd8, 0x113b0000)<br /> from space 2496K, 0% used [0x113b0000, 0x113b0000, 0x11620000)<br /> to space 2496K, 0% used [0x11620000, 0x11620000, 0x11890000)<br /> tenured generation total 190696K, used 100019K [0x138f0000, 0x1f32a000, 0x30010000)<br /> the space 190696K, 52% used [0x138f0000, 0x19a9cf38, 0x19a9d000, 0x1f32a000)<br /> compacting perm gen total 38656K, used 38588K [0x30010000, 0x325d0000, 0x34010000)<br /> the space 38656K, 99% used [0x30010000, 0x325bf038, 0x325bf200, 0x325d0000)<br /> ----------------------------------------------------------------</p> <p><br /> 上面的信息能看出在Crash的时候，JVM的PermSize空间几乎已经消耗完了，并且回收算法在压缩Perm空间的时候出了错。</p> <p>因此，建议改变内存回收的算法，或扩大PermSize和MaxPermSize的数值。</p> <p>（*******这个倒是可以尝试*******）</p> <p>五.栈溢出引起的Crash</p> <p>Java代码引起的栈溢出，通常不会引起JVM的Crash，而是抛出一个Java异常：java.lang.StackOverflowError。</p> <p>但是在Java虚拟机中，Java的代码和本地C或C++代码公用相同的Stack。这样，在执行本地代码所造成的栈溢出，</p> <p>就有可能引起JVM的Crash了。</p> <p>栈溢出引起的Crash会在日志的文件头中看到&#8220;EXCEPTION_STACK_OVERFLOW&#8221;字样。另外，在当前线程的Stack</p> <p>信息中也能发现一些信息。例如下面的例子：</p> <p>-----------------------------------------------------------------------------------<br /> # An unexpected error has been detected by HotSpot Virtual Machine:<br /> #<br /> # EXCEPTION_STACK_OVERFLOW (0xc00000fd) at pc=0x10001011, pid=296, tid=2940<br /> #<br /> # Java VM: Java HotSpot(TM) Client VM (1.6-internal mixed mode, sharing)<br /> # Problematic frame:<br /> # C [App.dll+0x1011]<br /> #<br /> --------------- T H R E A D ---------------<br /> Current thread (0x000367c0): JavaThread "main" [_thread_in_native, id=2940]<br /> :<br /> Stack: [0x00040000,0x00080000), sp=0x00041000, free space=4k<br /> Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)<br /> C [App.dll+0x1011]<br /> C [App.dll+0x1020]<br /> C [App.dll+0x1020]<br /> :<br /> C [App.dll+0x1020]<br /> C [App.dll+0x1020]<br /> ...&lt;more frames&gt;...<br /> Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)<br /> j Test.foo()V+0<br /> j Test.main([Ljava/lang/String;)V+0<br /> v ~StubRoutines::call_stub</p> <p>--------------------------------------------------------------------------------</p> <p>在上面的信息中，可以发现这是个栈溢出的错误。并且当前栈剩余的空间已经很小了(free space =4k)。</p> <p>因此建议将JVM的Stack的尺寸调大，主要设计两个参数：&#8220;-Xss&#8221; 和&#8220;-XX:StackShadowPages=n&#8221;。</p> <p>但是，将栈的尺寸调大，也意味着在有限的内存资源中，能打开的最大线程数会减少。</p> <p>&nbsp;（******俺的栈剩余还有free space=254k，显然不符，于是乎我决定假期再解决，o(&#8745;_&#8745;)o...******）</p> <p>结论：</p> <p>我觉得还是C++建立Java对象后，没有回收-----------------鉴定完毕</p> <p>&nbsp;</p> <p>不知园子里可否有人有其他的建议。欢迎提出！</p> <p>这个问题发到两个JavaQQ群都没动静，于是决定自己解决，看来越往后越要靠自己了。</p> </div></div><img src ="http://www.blogjava.net/kuuyee/aggbug/355030.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/kuuyee/" target="_blank">kuuyee</a> 2011-07-26 09:49 <a href="http://www.blogjava.net/kuuyee/articles/355030.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>