JVM致命错误日志详解

本文详细解析了JVM在遇到致命错误时生成的错误日志,包括文件描述、线程、进程、系统信息等部分,并通过对错误日志的分析,探讨了可能的崩溃原因,如JNI调用问题、内存溢出和JDK版本兼容性等,为问题排查提供了方向。
摘要由CSDN通过智能技术生成


最近一段时间生产环境频繁出问题,每次都会生成一个hs_err_pid*.log文件,因为工作内容的原因,之前并没有了解过相关内容,趁此机会学习下,根据项目的使用情况,此文章针对JDK 8进行分析,不过因为素材问题,文章中引用的文件内容为JDK 7生成的文件,此处应该不影响,因为官方文档中关于此部分说明使用的是JDK 6生成的文件。我们将按照内容在文件中出现的顺序进行介绍。

PS:本人水平有限,工作中也没有太多机会进行此类知识的应用,文章内容绝大多数来自于官方文档,某些内容在官网中并没有涉及,相应的介绍不一定准确,希望各位大佬不吝赐教

JDK 8
官方文档下载地址:https://www.oracle.com/java/technologies/javase-jdk8-doc-downloads.html
致命错误日志文档:/docs/technotes/guides/troubleshoot/felog.html#fatal_error_log_vm

JDK 7
官方文档地址:https://docs.oracle.com/javase/7/docs/
致命错误日志文档:https://docs.oracle.com/javase/7/docs/webnotes/tsg/TSG-VM/html/felog.html

文件描述

错误日志是在JVM遇到致命错误时生成的日志文件,可能包括以下信息:

  • 引发致命错误的异常操作或信号
  • 版本和配置信息
  • 引发致命错误的线程详细信息和线程堆栈记录
  • 正在运行的线程及其状态的列表
  • 有关堆的概要信息
  • 加载的本机库的列表
  • 命令行参数
  • 环境变量
  • 操作系统和 CPU 的详细信息

当问题严重到错误处理器无法收集并报告所有信息时,可能只有一部分信息会写入错误日志。

文件总共分为一下几个章节:

  • 简单描述崩溃信息的文件头
  • 线程描述部分
  • 进程描述部分
  • 系统信息部分

文件位置

致命错误日志文件位置可以通过 -XX:ErrorFile进行指定,例如:

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

以上设置表示文件会放在/var/log/java目录下,%p表示进程的PID。如果不设置XX:ErrorFile属性,日志默认生成在执行java命令的目录下,文件名默认为hs_err_pid%p.log,如果该目录因为某种情况无法写入(空间不足,权限不足等),在linux系统下默认写到/tmp目录下,windows系统下默认使用环境变量中TMP对应的目录,如果没有则使用TEMP对应的目录(TMP和TEMP均为windows默认的环境变量,且默认值一样)。

文件头

文件头在错误日志的最开头,主要是对问题的简单描述。这部分内容同样会打印到标准输出,可能也会打印到应用程序的控制台上。示例如下:

# 
# A fatal error has been detected by the Java Runtime Environment: 
# 
#  SIGSEGV (0xb) at pc=0x00007f80e0cd095c, pid=48, tid=140189843019520 
# 
# JRE version: Java(TM) SE Runtime Environment (7.0_80-b15) (build 1.7.0_80-b15)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (24.80-b11 mixed mode linux-amd64 compressed oops) 
# Problematic frame: 
# V  [libjvm.so+0x65395c]  jni_SetByteArrayRegion+0x19c 
# 
# Core dump written. Default location: /apps/gateway/project/bin/core or core.48
#
# If you would like to submit a bug report, please visit:
#   http://bugreport.java.com/bugreport/crash.jsp 
#  

错误信息记录

前两行主要描述了信号类型、发起信号的程序计数器、进程ID和线程ID,如下所示:

#  SIGSEGV (0xb) at pc=0x00007f80e0cd095c, pid=48, tid=140189843019520
      |      |           |                    |       |
      |      |           |                    |       +--- 线程ID
      |      |           |                    +----------- 进程ID
      |      |           +-------------------------------- 程序计数器对应的指针
      |      +-------------------------------------------- 信号值(十六进制)
      +--------------------------------------------------- 信号名称

信号名称是操作系统自身的一种信息,CentOS 7下共有以下35种,可在/usr/include/bits/signum.h中查看其具体的声明

信号名称 信号值 含义
SIGHUP 1 Hangup (POSIX).
SIGINT 2 Interrupt (ANSI).
SIGQUIT 3 Quit (POSIX).
SIGILL 4 Illegal instruction (ANSI).
SIGTRAP 5 Trace trap (POSIX).
SIGABRT 6 Abort (ANSI).
SIGIOT 6 IOT trap (4.2 BSD).
SIGBUS 7 BUS error (4.2 BSD).
SIGFPE 8 Floating-point exception (ANSI).
SIGKILL 9 Kill, unblockable (POSIX).
SIGUSR1 10 User-defined signal 1 (POSIX).
SIGSEGV 11 Segmentation violation (ANSI).
SIGUSR2 12 User-defined signal 2 (POSIX).
SIGPIPE 13 Broken pipe (POSIX).
SIGALRM 14 Alarm clock (POSIX).
SIGTERM 15 Termination (ANSI).
SIGSTKFLT 16 Stack fault.
SIGCLD SIGCHLD Same as SIGCHLD (System V).
SIGCHLD 17 Child status has changed (POSIX).
SIGCONT 18 Continue (POSIX).
SIGSTOP 19 Stop, unblockable (POSIX).
SIGTSTP 20 Keyboard stop (POSIX).
SIGTTIN 21 Background read from tty (POSIX).
SIGTTOU 22 Background write to tty (POSIX).
SIGURG 23 Urgent condition on socket (4.2 BSD).
SIGXCPU 24 CPU limit exceeded (4.2 BSD).
SIGXFSZ 25 File size limit exceeded (4.2 BSD).
SIGVTALRM 26 Virtual alarm clock (4.2 BSD).
SIGPROF 27 Profiling alarm clock (4.2 BSD).
SIGWINCH 28 Window size change (4.3 BSD, Sun).
SIGPOLL SIGIO Pollable event occurred (System V).
SIGIO 29 I/O now possible (4.2 BSD).
SIGPWR 30 Power failure restart (System V).
SIGSYS 31 Bad system call.
SIGUNUSED 31 -

JVM运行信息

接下来两行描述了JVM相关版本信息及运行配置信息,内容如下:

# JRE version: Java(TM) SE Runtime Environment (7.0_80-b15) (build 1.7.0_80-b15)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (24.80-b11 mixed mode linux-amd64 compressed oops)

上述文件内容可以得知以下几点:

  • JRE版本号为1.7u80
  • JVM版本号为24.80-b11
  • JVM运行在Server模式下。对应的是Client模式,Client JVM适合需要快速启动和较小内存空间的应用,它适合交互性的应用,比如GUI;而Server JVM则是看重执行效率的应用的最佳选择,更适合服务端应用。
  • JVM运行在混合模式下,即mixed mode,是JVM默认的运行模式。其他模式还有解释模式(interpreted mode)和编译模式(compiled mode),解释模式会强制JVM以解释方式执行所有的字节码,编译模式下JVM在第一次使用时会把所有的字节码编译成本地代码,这两种模式各有优劣,单独使用时都会有部分性能上的损失,所以默认使用混合模式即可,混合模式下对于字节码中多次被调用的部分,JVM会将其编译成本地代码以提高执行效率;而被调用很少(甚至只有一次)的方法在解释模式下会继续执行,从而减少编译和优化成本。

崩溃原因

接下来两行描述了引发崩溃问题的函数帧

# Problematic frame:
# V  [libjvm.so+0x65395c]  jni_SetByteArrayRegion+0x19c
  |              |
  |              +-- 类似于程序计数器, 以库名和偏移量表示。
  |                  对于与位置无关的库(JVM和其他库),可以不通过
  |                  调试器或通过反汇编程序转存偏移量周围结
  |                  
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值