`

JVM Crash日志分析

    博客分类:
  • JAVA
 
阅读更多

JVM Crash日志分析

转自:http://book.51cto.com/art/201408/448846.htm

8.7.3  JVM Crash日志分析(1)

JVM有时也会因为一些原因而导致直接垮掉,因为JVM本身也是一个正在运行的程序,这个程序本身也会有很多情况直接出问题,如JVM本身也有一些Bug,这些Bug可能会导致JVM异常退出。JVM退出一般会在工作目录下产生一个日志文件,也可以通过JVM参数来设定,如-XX:ErrorFile=/tmp/log/hs_error_%p.log。

下面是一个日志文件:
 

  1. #  
  2. # A fatal error has been detected by the Java Runtime Environment:  
  3. #  
  4. #  SIGSEGV (0xb) at pc=0x00002ab12ba7103apid=7748tid=1363515712 
  5. #  
  6. # JRE version: 6.0_26-b03  
  7. # Java VM: OpenJDK 64-Bit Server VM (20.0-b11-internal mixed mode linux- amd64 )  
  8. # Problematic frame:  
  9. # V  [libjvm.so+0x8bf03a]  jni_GetFieldID+0x22a  
  10. #  
  11. # If you would like to submit a bug report, please visit:  
  12. #   http://java.sun.com/webapps/bugreport/crash.jsp  
  13. #  
  14. ---------------  T H R E A D  ---------------  
  15. Current thread (0x00002aabd0ba5000):  JavaThread "http-0.0.0.0-7001-32" daemon [_thread_in_vm, id=8192, stack(0x0000000051359000,0x000000005145a000)]  
  16.  
  17. siginfo:si_signo=SIGSEGVsi_errno=0si_code=1 (SEGV_MAPERR), si_addr0x0000000000000010 
  18.  
  19. Registers:  
  20. ...  
  21. Top of Stack: (sp=0x0000000051455620)  
  22. ...  
  23. Instructions: (pc=0x00002ab12ba7103a)  
  24. 0x00002ab12ba7101a:   01 00 00 48 8b 5f 10 48 8d 43 08 48 3b 47 18 0f  
  25. 0x00002ab12ba7102a:   87 53 02 00 00 48 89 47 10 48 89 13 48 83 c2 10  
  26. 0x00002ab12ba7103a:   48 8b 0a 48 89 d7 4c 89 fe 31 c0 ff 51 58 49 8b  
  27. 0x00002ab12ba7104a:   47 08 48 85 c0 0f 85 f7 01 00 00 48 c7 45 90 00   
  28. Register to memory mapping:  
  29.  
  30. RAX=  
  31. [error occurred during error reporting (printing register info), id 0xb]  
  32.  
  33. Stack: [0x0000000051359000,0x000000005145a000],  sp=0x0000000051455620,  free space=1009k 
  34. Native frames: (J=compiled Java code, j=interpretedVv=VM code, C=native code)  
  35. V  [libjvm.so+0x8bf03a]  jni_GetFieldID+0x22a  
  36. C  [libocijdbc10.so+0xcc81]  Java_oracle_jdbc_driver_T2CConnection_ t2cDescribeError+0x205  
  37. C  [libocijdbc10.so+0x878b]  Java_oracle_jdbc_driver_T2CConnection_ t2cCreateState+0x193  
  38. j  oracle.jdbc.driver.T2CConnection.t2cCreateState([BI[BI[BI[BISI[S[B[B]I+0  
  39. j  oracle.jdbc.driver.T2CConnection.logon()V+589  
  40. j  oracle.jdbc.driver.PhysicalConnection.<init>(Ljava/lang/String;Ljava/ lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/Properties;Loracle/jdbc/driver/OracleDriverExtension;)V+370  
  41. j  oracle.jdbc.driver.T2CConnection.<init>(Ljava/lang/String;Ljava/lang/ String;Ljava/lang/String;Ljava/lang/String;Ljava/util/Properties;Loracle/jdbc/driver/OracleDriverExtension;)V+10  
  42. j  oracle.jdbc.driver.T2CDriverExtension.getConnection(Ljava/lang/String; Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/Properties;)Ljava/sql/Connection;+67  
  43. j  oracle.jdbc.driver.OracleDriver.connect(Ljava/lang/String;Ljava/util/ Properties;)Ljava/sql/Connection;+831  
  44. ...  
  45. ---------------  P R O C E S S  ---------------  
  46.  
  47. Java Threads: ( => current thread )  
  48.   0x000000004d11e800 JavaThread "IdleRemover" daemon [_thread_blocked, id=8432, stack(0x00000000584ca000,0x00000000585cb000)]  
  49. =>0x00002aabd0ba5000 JavaThread "http-0.0.0.0-7001-32" daemon [_thread_in_ vm, id=8192, stack(0x0000000051359000,0x000000005145a000)]  
  50. ...  
  51. VM state:not at safepoint (normal execution)  
  52.  
  53. VM Mutex/Monitor currently owned by a thread: None  
  54.  
  55. Heap  
  56.  par new generation   total 1474560K, used 1270275K [0x00002aaaae0f0000, 0x00002aab120f0000, 0x00002aab120f0000)  
  57.   eden space 1310720K,  89% used [0x00002aaaae0f0000, 0x00002aaaf5d634e0, 0x00002aaafe0f0000)  
  58.   from space 163840K,  57% used [0x00002aab080f0000, 0x00002aab0dcfd748, 0x00002aab120f0000)  
  59.   to   space 163840K,   0% used [0x00002aaafe0f0000, 0x00002aaafe0f0000, 0x00002aab080f0000)  
  60.  concurrent mark-sweep generation total 2555904K, used 888664K [0x00002aab120f0000, 0x00002aabae0f0000, 0x00002aabae0f0000)  
  61.  concurrent-mark-sweep perm gen total 262144K, used 107933K [0x00002aabae0f0000, 0x00002aabbe0f0000, 0x00002aabbe0f0000)  
  62.  
  63. Code Cache  [0x00002aaaab025000, 0x00002aaaabcd5000, 0x00002aaaae025000)  
  64.  total_blobs=3985 nmethods=3447 adapters=491 free_code_cache=37205440 largest_free_block=30336 
  65.  
  66. Dynamic libraries:  
  67. 40000000-40009000 r-xp 00000000 ca:06 224241                             /opt/ xxx/install/jdk-1.6.0_26/bin/java  
  68. ...  
  69. ---------------  S Y S T E M  ---------------  
  70.  
  71. OS:Red Hat Enterprise Linux Server release 5.4 (Tikanga) 

在这个文件中的信息主要分为4种:退出原因分类、导致退出的Thread信息、退出时的Process状态信息、退出时与操作系统相关信息。

JVM退出一般有三种主要原因,在上面这个例子中是SIGSEGV(0xb),这三种原因分别如下。

1.EXCEPTION_ACCESS_VIOLATION

正在运行JVM自己的代码,而不是外部的Java代码或其他类库代码。这种情况很可能是JVM自己的Bug,遇到这种错误时,可以根据出错信息到http://bugreport.sun.com/bugreport/index.jsp去搜索一下已经发行的Bug。

在大部分情况下是由于JVM的内存回收导致的,所以可以观察Process部分的信息,查看堆的内存占用情况。

2.SIGSEGV

JVM正在执行本地或JNI的代码,出这种错误很可能是第三方的本地库有问题,可以通过gbd和core文件来分析出错原因。

3.EXCEPTION_STACK_OVERFLOW

这是个栈溢出的错误,注意JVM在执行Java线程时出现的栈溢出通常不会导致JVM退出,而是抛出java.lang.StackOverflowError,但是在Java虚拟机中,Java的代码和本地C或C++代码共用相同的栈,这时如果出现栈溢出的话,就有可能直接导致JVM退出。建议将JVM的栈尺寸调大,主要涉及两个参数:-Xss和-XX:StackShadowPages=n。

日志文件的Thread部分的信息对我们排查这个问题的原因最有帮助,这部分有两个关系信息,包括Machine Instructions和Thread Stack。Mchine Instructions是当前系统执行的机器指令,是16进制的。我们可以将它转成指令,通过udis86工具来转换,该工具可以在http://udis86.sourceforge.net/?下载,安装在Linux中,将上面的16进制数字复制到命令行中用如下方式执行转换:
 

  1. [junshan@xxx ~]$ echo "47 08 48 85 c0 0f 85 f7 01 00 00 48 c7 45 90 00"  | udcli -64 -x  
  2. 0000000000000000 47084885         or [r8-0x7b], r9b         
  3. 0000000000000004 c00f85           ror byte [rdi], 0x85      
  4. 0000000000000007 f701000048c7     test dword [rcx], 0xc7480000  
  5. 000000000000000d 4590             xchg r8d, eax  

可以得到汇编指令,由于是64位机器,所以是udcli -64 –x,如果是32机器,则改成udcli -32 –x。可以通过这个指令来判断当前正在执行什么指令而导致了垮掉。例如,如果当前在访问寄存器地址,那么这个地址是否合法,以及如果是除法指令,操作数是否合法等。

8.7.3  JVM Crash日志分析(2)

而Stack信息最直接,可以帮助我们看到到底是哪个库的哪行代码出错,如在上面的错误信息中显示的是由于执行Oracle的Java驱动程序引起出错的。我们还可以通过生成的core文件来更详细地看出是执行到哪行代码出错的,如下所示:
 

  1. $gdb /opt/xxx/java/bin/java /home/admin/xxxx/target/core.14595      
  2. GNU gdb Fedora (6.8-37.el5)  
  3. Copyright (C) 2008 Free Software Foundation, Inc.  
  4. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/ gpl.html> 
  5. This is free software: you are free to change and redistribute it.  
  6. There is NO WARRANTY, to the extent permitted by law.  Type "show copying"  
  7. and "show warranty" for details.  
  8. This GDB was configured as "x86_64-redhat-linux-gnu"...  
  9. …  
  10. (gdb) bt  
  11. #0  0x000000320ea30265 in raise () from /lib64/libc.so.6  
  12. #1  0x000000320ea31d10 in abort () from /lib64/libc.so.6  
  13. #2  0x00002b4ba59d80e9 in os::abort () from /opt/taobao/install/jdk-1.6.0_ 26/jre/lib/amd64/server/libjvm.so  
  14. #3  0x00002b4ba59d1e0f in VMError::report_and_die () from /opt/taobao/ install/jdk-1.6.0_26/jre/lib/amd64/server/libjvm.so  
  15. … 

通过gdb来调试core文件可以看到更详细的信息,还可以通过frame n和info local组合命令来更进一步地查看这一行所包含的local变量值,但这只能是程序使用-g命名编译的结果,也就是编译后的程序包含debug信息。

日志文件的第三部分包含的是Process信息,这里详细列出了该程序产生的所有线程,以及线程正处于的状态。由于在同一时刻只能有一个线程具有CPU使用权,所以可以看到,其他所有线程的状态都是_thread_blocked,而执行的正是那个出错的线程。

这部分最有价值的部分就是记录下来了当前JVM的堆信息,如下所示:
 

  1. Heap  
  2.  par new generation   total 1474560K, used 1270275K [0x00002aaaae0f0000, 0x00002aab120f0000, 0x00002aab120f0000)  
  3.   eden space 1310720K,  89% used [0x00002aaaae0f0000, 0x00002aaaf5d634e0, 0x00002aaafe0f0000)  
  4.   from space 163840K,  57% used [0x00002aab080f0000, 0x00002aab0dcfd748, 0x00002aab120f0000)  
  5.   to   space 163840K,   0% used [0x00002aaafe0f0000, 0x00002aaafe0f0000, 0x00002aab080f0000)  
  6.  concurrent mark-sweep generation total 2555904K, used 888664K [0x00002aab120f0000, 0x00002aabae0f0000, 0x00002aabae0f0000)  
  7.  concurrent-mark-sweep perm gen total 262144K, used 107933K [0x00002aabae0f0000, 0x00002aabbe0f0000, 0x00002aabbe0f0000] 

通过每个分区当前所使用的空间大小,尤其是Old区的空间是否已经满了,可以判断出当前的GC是否正常。

还有一个信息也比较有价值,那就是当前JVM的启动参数,设置的堆大小和使用的GC方式等都可以从这里看出。

最后一部分是System信息,这部分主要记录了当前操作系统的状态信息,如操作系统的CPU信息和内存情况等。

分享到:
评论

相关推荐

    JVM crash 错误日志分析

    在Java开发过程中,JVM(Java Virtual ...总之,JVM崩溃日志分析是一个细致的过程,需要结合代码、日志和各种工具来定位问题。通过深入学习和实践,开发者可以更好地理解和处理这类问题,确保Java应用的稳定运行。

    jvm crash的崩溃日志详细分析及注意点

    分析JVM崩溃日志时,重点是定位问题所在的代码行,了解触发错误的操作,以及查看是否有内存管理问题,如堆溢出或栈溢出。同时,还要检查堆栈跟踪,确定哪些线程或方法在崩溃时刻正在执行,并结合Java堆、方法区、元...

    年轻代gc jvm crash

    "年轻代GC JVM crash"可能是因为在垃圾回收过程中遇到了严重问题,导致JVM崩溃。这可能是由于以下原因: 1. **内存溢出**:如果年轻代的空间不足以容纳新分配的对象,或者Survivor区无法容纳从Eden区晋升的对象,就...

    JVM Crash,生成hs_err_pid.log文件

    标题"JVM Crash,生成hs_err_pid.log文件"指的是Java虚拟机在运行过程中遇到了致命问题,导致其终止运行,并自动生成了一个错误日志文件。这个文件通常位于JVM崩溃时的工作目录下,文件名由“hs_err_pid”和进程ID...

    hs-err-pidXXX.log 文件分析利器

    # CrashAnalysis ## 功能介绍 这是一个jvm crash分析工具,主要分析jvm crash的原因,...${hs_err_pid.log} 是jvm crash后生成的日志。 ## 效果 分析完成后会展示出来诊断信息,其他信息都是用来验证诊断信息的。

    jvm日志解读

    《JVM日志解读——揭示Java虚拟机的秘密》 在Java开发中,JVM(Java Virtual Machine)扮演着至关重要的角色。它负责运行我们的代码,管理内存,执行垃圾收集等。当程序出现异常或者性能问题时,JVM生成的日志文件...

    系统core和java虚拟机异常退出日志设置

    这将使得Java虚拟机崩溃日志被保存在$PM4H_EXTLOG/jvm目录下,并且文件名格式为jvm_crash_&lt;模块名称&gt;.log。 对于JBoss应用,我们可以在JBoss的配置文件中添加以下参数: JVM_CRASH_LOG="-XX:ErrorFile=$PM4H_...

    01 JVM崩块案例分析

    Crash崩溃日志

    java 虚拟机问题分析大全

    - **GC日志分析**:通过设置合理的JVM参数来收集GC日志,并使用工具如GC Log Analyzer、VisualVM等分析GC行为,优化垃圾回收策略。 - **代码优化**:根据性能分析的结果,针对性地优化代码逻辑,减少不必要的对象...

    java线上故障分析-线程dump,堆内存分析

    在提供的案例中,可以看到JVM crash的日志信息。其中,`SIGSEGV`信号表示非法存储访问错误,这通常意味着程序尝试访问不可访问的内存区域,可能是由于第三方库的问题。此外,日志还记录了导致问题的动态链接库函数...

    crash-dump-analysis:Java Crash Dump 分析演示的示例代码

    8. **实战经验**:实际操作中,分析Crash Dump需要结合日志、代码逻辑和业务场景,有时还需要复现问题。通过多次实践,开发者可以积累经验,提高问题解决速度。 9. **最佳实践**:定期生成和检查堆转储可以作为日常...

    JDK15-troubleshooting-guide.pdf

    2. Java 虚拟机(JVM)的故障排除:该指南提供了 JVM 故障排除的方法和步骤,包括 JVM crash 的原因分析、堆栈跟踪的获取、JVM 配置文件的编辑等。 3. Java 应用程序的故障排除:该指南介绍了 Java 应用程序的故障...

    基于Java的开发的SHELL CRaSH.zip

    5. **调试与日志**:CRaSH提供了丰富的日志选项,可以帮助开发者在开发和调试过程中跟踪命令的执行过程和输出。 6. **扩展性**:CRaSH的灵活性使其易于扩展。开发者可以根据需求添加自定义命令,甚至实现自己的命令...

    Java开发的SHELL CRaSH.7z

    在IT行业中,Java是一种广泛应用的编程语言...综上所述,"Java开发的SHELL CRaSH.7z"可能是一个包含Java代码、Shell脚本、错误日志或其他相关资源的项目。要深入了解这个问题,我们需要解压文件并详细分析其中的内容。

    hs_err_pid10988.log

    java进程崩溃日志 以下为几种可能的原因: Java应用程序的问题:发生OOM导致进程Crash; JVM出错:JVM或JDK自身的Bug导致进程Crash; 被操作系统OOM-Killer;

    Java开发的SHELL CRaSH.gz

    它支持JMX(Java Management Extensions),可以与JVM管理工具集成,提供实时监控和性能分析。 2. **SSH集成**:CRaSH与SSH紧密结合,使得用户能够安全地通过SSH连接到运行中的Java应用,并执行自定义命令,进行...

    java1.8.zip

    Java 1.8,也被称为Java 8...在处理这类问题时,一个系统的故障排查方法至关重要,包括复现问题、收集信息、分析日志、定位问题源,最后实施修复措施。同时,定期更新JDK和保持良好的编程习惯也是预防问题的有效手段。

    Linux服务器Java进程消失问题解决

    当 JVM 发生致命错误导致崩溃时,会生成一个 hs_err_pid_xxx.log 这样的文件,该文件包含了导致 JVM Crash 的重要信息,我们可以通过分析该文件定位到导致 JVM Crash 的原因,从而修复保证系统稳定。 默认情况下,...

    经典:WebSphere应用服务器故障诊断上机实验

    - **JVM Crash问题诊断**:探讨导致JVM崩溃的常见原因,如OutOfMemoryError等,并学习如何通过日志文件和其他诊断工具定位问题。 通过本次实验,参与者不仅能深入理解WebSphere应用服务器的工作原理和潜在问题,还...

Global site tag (gtag.js) - Google Analytics