触发JVM fatal error并配置相关JVM参数

这篇具有很好参考价值的文章主要介绍了触发JVM fatal error并配置相关JVM参数。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1. 絮絮叨叨

  • 工作中,Java服务因为fatal error(致命错误,笔者称其为jvm crash),在服务运行日志中出现了致命错误的概要信息:

    #
    # A fatal error has been detected by the Java Runtime Environment:
    #
    #  SIGSEGV (0xb) at pc=0x000000010a7d52e8, pid=47989, tid=11011
    #
    # JRE version: OpenJDK Runtime Environment Temurin-17.0.6+10 (17.0.6+10) (build 17.0.6+10)
    # Java VM: OpenJDK 64-Bit Server VM Temurin-17.0.6+10 (17.0.6+10, mixed mode, sharing, tiered, compressed oops, compressed class ptrs, g1 gc, bsd-amd64)
    # Problematic frame:
    # V  [libjvm.dylib+0xada2e8]  Unsafe_GetByte(JNIEnv_*, _jobject*, _jobject*, long)+0xd8
    #
    # No core dump will be written. Core dumps have been disabled. To enable core dumping, try "ulimit -c unlimited" before starting Java again
    #
    # An error report file with more information is saved as:
    # /Users/xxx/IdeaProjects/study/hs_err_pid47989.log
    #
    # If you would like to submit a bug report, please visit:
    #   https://github.com/adoptium/adoptium-support/issues
    #
    
  • 服务运行在k8s中,由于未提前设置fatal error日志的路径(挂载到宿主机目录),容器重启后该日志会丢失,无法深入排查原因

  • 因此,需要查询jvm的配置,将fatal error日志写入指定目录,保证该日志持久化存储到宿主机磁盘

2. 配置jvm参数,实现日志的持久化存储

2.1 -XX:ErrorFile配置fatal error路径

  • 通过查阅资料,了解到可以通过-XX:ErrorFile=filename配置hs_err日志的路径

  • 下面的示例中,将fatal error的日志写入指定目录,文件名的%p会动态替换成改Java程序的PID(进程id)

    -XX:ErrorFile=/var/log/java/java_error%p.log
    
  • 默认将fatal error日志写入Java程序的working directory,且文件名为hs_err_pid.log;如果空间不足、权限不够等原因,fatal error日志将被写入系统的临时目录

  • 详情见JDK官网的说明:

    • JDK 8:A Fatal Error Log
    • JDK 17:A Fatal Error Log,Command-Line Options

2.2 笔者的错误配置

  • 考虑到服务每次重启的pid基本一致,如果多次出现fatal error,只使用pid的日志会被覆盖。

  • 笔者结合之前配置heap dump的经验,添加了%t以生成类似2023-08-16_23-33-08的时间戳

    -XX:ErrorFile=/data_path/var/log/hs_err_pid%p_%t.log
    
  • 当再一次发生fatal error时,发现日志文件名为hs_err_pid6_%t.log,即%t未按照预期进行解析

2.3 -XX:OnError配置更新文件名

  • 受问题(How to specify a unique name for the JVM crash log files?)启发,配置-XX:OnError:在日志生成后,执行shell命令为其添加时间戳

    -XX:ErrorFile=/data_path/var/log/hs_err.log
    -XX:OnError="time=`date +%Y%m%d_%H%M%S` && mv /data_path/var/log/hs_err.log /data_path/var/log/hs_err_\${time}.log"
    

3. 如何触发fatal error?

  • 不管是验证相关JVM参数的配置,还是学习查看fatal error日志的内容,学会如何在触发fatal error是非常必要的

  • 参考:Write Java code to crash the java virtual machine,通过如下代码可以成功在本地触发fatal error

    import sun.misc.Unsafe;
    import java.lang.reflect.Field;
    
    public class CrashTest {
        public static void main(String... args) throws Exception {
            getUnsafe().getByte(0);
        }
    
        private static Unsafe getUnsafe() throws NoSuchFieldException, IllegalAccessException {
            Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
            theUnsafe.setAccessible(true);
            return (Unsafe) theUnsafe.get(null);
        }
    }
    

4. 待交流的问题

4.1 本地验证OK

  • 按照上面的描述,笔者为CrashTest配置了如下JVM参数

    -XX:ErrorFile=/data_path/study/hs_err.log
    -XX:OnError="time=`date +%Y%m%d_%H%M%S` && echo $time && mv /data_path/hs_err.log /data_path//hs_err_${time}.log"
    
  • 程序运行起来后,打印如下信息:

    #
    # A fatal error has been detected by the Java Runtime Environment:
    #
    #  SIGSEGV (0xb) at pc=0x000000010a49e2e8, pid=56245, tid=11011
    #
    # JRE version: OpenJDK Runtime Environment Temurin-17.0.6+10 (17.0.6+10) (build 17.0.6+10)
    # Java VM: OpenJDK 64-Bit Server VM Temurin-17.0.6+10 (17.0.6+10, mixed mode, sharing, tiered, compressed oops, compressed class ptrs, g1 gc, bsd-amd64)
    # Problematic frame:
    # V  [libjvm.dylib+0xada2e8]  Unsafe_GetByte(JNIEnv_*, _jobject*, _jobject*, long)+0xd8
    #
    # No core dump will be written. Core dumps have been disabled. To enable core dumping, try "ulimit -c unlimited" before starting Java again
    #
    # An error report file with more information is saved as:
    # /data_path/hs_err.log
    #
    # If you would like to submit a bug report, please visit:
    #   https://github.com/adoptium/adoptium-support/issues
    #
    #
    # -XX:OnError="time=`date +%Y%m%d_%H%M%S` && mv /data_path/hs_err.log /data_path/hs_err_${time}.log"
    #   Executing /bin/sh -c "time=`date +%Y%m%d_%H%M%S` && mv /data_path/hs_err.log /data_path/hs_err_${time}.log" ...
    
  • 最终,fatal error日志的文件名为hs_err_20230827_202458.log符合预期

4.2 测试环境验证失败

  • 将此配置移动到线上服务,却发现fatal error日志的文件名为hs_err_.log不符合预期

  • 怀疑: 未能正确解析${time}

  • 一个问答: How to add the timestamp of the fatal error occurrence to Java fatal error log filename,遇到了与笔者类似的问题

    -XX:ErrorFile={{ .Values.server.data_dir }}/var/log/hs_err.log
    -XX:OnError="mv {{ .Values.server.data_dir }}/var/log/hs_err.log {{ .Values.server.data_dir }}/var/log/hs_err_\$(date +%Y%m%d_%H%M%S).log"
    
  • 虽然更新了配置,但是由于引发fatal error的错误已被修复,无法验证该配置的效果

  • 要么等到后面出现fatal error时验证效果,要么回退镜像版本触发fatal error

  • 若后续有机会验证该配置,笔者会更新结果,暂时在此记录可能的可行解决方案文章来源地址https://www.toymoban.com/news/detail-684817.html

到了这里,关于触发JVM fatal error并配置相关JVM参数的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • jvm参数配置

    JVM(Java Virtual Machine)参数的配置对于Java应用程序的性能和行为具有重要影响。以下是一些常见的JVM参数及其说明: 堆内存相关参数: -Xms : 设置JVM初始堆内存大小。 -Xmx : 设置JVM最大堆内存大小。 -Xmn : 设置新生代堆内存大小。 -XX:MaxPermSize (JDK 7及之前) 或 -XX:MaxMetaspaceSize

    2024年01月24日
    浏览(31)
  • JVM 参数配置规范

    废话不说,直接上干货!!! JVM 规范: 参数 备注/参数释义 交易规范 JVM版本 1.8.0_60以下,无法使用Pfinder 1.8.0_131之前,jvm无法感知docker的真实核数和内存大小,而是使用的宿主机的核数和内存 必须1.8.0_60以上 推荐1.8.0_191以上 JVM GC方法 ParallelGC:1.8默认,高吞吐量,响应时间

    2024年02月16日
    浏览(33)
  • JVM——配置常用参数,GC调优策略

    Java内存区域常见配置参数概览 堆参数; 回收器参数; 项目中常用配置; 常用组合; Java内存区域常见配置参数概览 堆参数 回收器参数 如上表所示,目前 主要有串行、并行和并发三种 ,对于大内存的应用而言,串行的性能太低,因此使用到的主要是并行和并发两种。并行

    2024年02月12日
    浏览(42)
  • 常见JVM参数配置和GC性能优化

    常见的JVM参数配置 垃圾回收统计信息 -XX:+PrintGC     打印GC简要信息 -XX:+PrintGCDetails打印GC的详细信息 -XX:+PrintGCTimeStamps打印CG发生的时间戳 -Xloggc:log/gc.log 指定GC log的位置,以文件输出 -XX:+PrintHeapAtGC 每一次GC前和GC后,都打印堆信息。 堆设置 -Xms:初始堆大,最小堆 -Xmx:最大

    2024年02月16日
    浏览(43)
  • 【Java】JDK8 jvm参数配置及说明

    -Xms 或 -XX:InitialHeapSize=n 设置堆的初始值 指令1:-Xms2g 指令2:-XX:InitialHeapSize=2048m -Xmx 或 -XX:MaxHeapSize=n 设置堆区最大值 指令1: -Xmx2g 指令2: -XX:MaxHeapSize=2048m -XX:NewSize=n 设置年轻代大小 -Xss 或 -XX:ThreadStackSize=n 每个线程堆栈最大值 指令1:-Xss256k 指令2:-XX:ThreadStackSize=256k 注意:

    2024年02月03日
    浏览(53)
  • JVM堆内存及参数配置 -Xss -Xms -Xmx -Xmn

    目录 一 JVM堆内存划分 二 参数设置 逻辑上:新生代、老年代、永久代  物理上:新生代、 老年代 JDK1.7之前,有永久代,但已经逐步“去永久代” JDK1.8之后,无永久代,由元空间替代 java堆从GC的角度,可以细分为: 新生代(Eden区、From Survivor区、To Survivor区) 老年代 1、新

    2024年02月05日
    浏览(39)
  • TOMCAT部署及优化(Tomcat配置文件参数优化,Java虚拟机(JVM)调优)

    TOMCAT tomcat :是一个开放源代码的web应用服务器,基于java代码开发的。也可以理解为tomacat就是处理动态请求和基于java代码的页面开发。可以在html当中写入java代码,tomcat可以解析html页面当中的java,执行动态请求,动态页面。 tomcat是机制存在一些问题,如果不对tomcat进行优化

    2024年02月13日
    浏览(34)
  • [Java SE] 彻底搞懂Java程序的三大参数配置途径:系统变量与JVM参数(VM Option)/环境变量/启动程序参数args

    一次没搞懂,处处受影响。这个问题属于基础问题,但又经常踩坑,不得不重视一下了。 IDEA中的配置位置 参数 使用方式 示例 代码获取方式 系统属性 由操作系统、JVM、应用程序主动设置 System.setProperties(Properties propes) / System.setProperties(String key,String value) / System.getProperties(

    2024年02月08日
    浏览(42)
  • JVM——JVM参数指南

    在本篇文章中,你将掌握最常用的 JVM 参数配置。如果对于下面提到了一些概念比如堆、 Java 虚拟机所管理的内存中最大的一块,Java 堆是所有线程共享的一块内存区域,在虚拟机启动时创建。 此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例以及数组都在这里

    2024年02月12日
    浏览(40)
  • 什么时候会触发FullGC?描述一下JVM加载class文件的原理机制?

    什么时候会触发 FullGC? 除直接调用 System.gc 外,触发 Full GC 执行的情况有如下四种。 1. 旧生代空间不足 旧生代空间只有 在新生代对象转入及创建为大对象、大数组时才会出现不足的现象,当执行 Full GC 后空间仍然不 足,则抛出如下错误: java.lang.OutOfMemoryError: Java heap spac

    2024年02月20日
    浏览(46)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包