Java异常日志堆栈丢失的原因与排查

 更新时间:2020年11月10日 11:01:33   作者:Real_man  
这篇文章主要给大家介绍了关于Java异常日志堆栈丢失的原因与排查的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

前言

查日志是我们排查问题的重要手段之一,直接又方便。其中异常日志堆栈信息可以让我们快速的发现问题所在,但稍微有点经验的开发应该会遇到过日志堆栈信息丢失的情况。

堆栈只打印了一行:java.lang.NullPointerException,然后什么信息都没有了,这是怎么回事?
如果面试中,就可以提一些问题:

什么情况下Java的异常日志堆栈信息会丢失?其原因是什么? 异常堆栈丢失情况下要如何排查问题?

原因

JVM内部同一个方法被调用多次的时候,会被JIT编译器进行优化,在Oracle官方文档中,有一段英文描述:

The compiler in the server VM now provides correct stack backtraces for all "cold" built-in exceptions. For performance purposes, when such an exception is thrown a few times, the method may be recompiled. After recompilation, the compiler may choose a faster tactic using preallocated exceptions that do not provide a stack trace. To disable completely the use of preallocated exceptions, use this new flag: -XX:-OmitStackTraceInFastThrow.

在Server模式下的JVM编译器提供了一种方式可以让我们回溯异常的堆栈信息,但是出于性能的因素,当类似的异常抛出多次的时候,异常方法可以被重新编译,重新编译后,编译器会采用更快的策略使用预分配缓存区的异常,并且不再提供堆栈信息。

如果不想使用预分配缓存的异常使用-XX:-OmitStackTraceInFastThrow标记。

另外一方面异常栈的获取是非常消耗性能的,这点通过JVM内部默认会对一些异常不进行堆栈回溯也可以看出。

异常丢失如何排查

  • 试着隔离一两台机器,重启两台机器观察情况
  • -XX:-OmitStackTraceInFastThrow可以控制不进行异常堆栈优化,如果关闭,就需要预防产生“日志风暴”,否则,一旦高频应用出现异常可能很快用满服务器磁盘。

验证堆栈丢失Demo

public class ExceptionLossDemo {
 public static void main(String[] args) {
  boolean flag = false;
  for (int i = 0;;i++){
   boolean isExceptionStackLoss = exceptionTest();
   if (isExceptionStackLoss) {
    flag = true;
    System.out.println("times:" + i + ", res:" + isExceptionStackLoss);
   } else if (flag) {
    System.out.println("times:" + i + ", res:" + isExceptionStackLoss);
   }
  }
 }

 public static boolean exceptionTest() {
  try {
   // 构造一个NPE异常
   int res = ((Integer)null) + 1;
  } catch (Exception e) {
   if (e.getStackTrace().length == 0) {
    // 打印堆栈信息
    e.printStackTrace();
    try {
     // 当出现 NPE 异常堆栈为空的时候,停留5秒,便于观察
     Thread.sleep(5000);
    } catch (Exception e1) {
    }
    // 如果出现 NPE 异常堆栈为空,返回true
    return true;
   }
   // 打印堆栈信息
   e.printStackTrace();
  }

  return false;
 }
}

最后

希望对大家有所帮助,技术不断精进..

到此这篇关于Java异常日志堆栈丢失的原因与排查的文章就介绍到这了,更多相关Java异常日志堆栈丢失内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • SpringBoot内嵌tomcat处理有特殊字符转义的问题

    SpringBoot内嵌tomcat处理有特殊字符转义的问题

    这篇文章主要介绍了SpringBoot内嵌tomcat处理有特殊字符转义的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-06-06
  • Java Agent入门学习之动态修改代码

    Java Agent入门学习之动态修改代码

    这篇文章主要给大家分享了Java Agent入门学习之动态修改代码的相关资料,文中介绍的非常详细,对大家具有一定的参考学习价值,需要的朋友们下面来一起看看吧。
    2017-07-07
  • 使用SSM+Layui+Bootstrap实现汽车维保系统的示例代码

    使用SSM+Layui+Bootstrap实现汽车维保系统的示例代码

    本文主要实现对汽车维修厂的信息化管理功能,。实现的主要功能包含用户管理、配置管理、汽车管理、故障管理、供应商管理、配件管理、维修订单管理、统计信息、公告管理、个人信息管理,感兴趣的可以了解一下
    2021-12-12
  • Mybatis 动态sql的编写与开启二级缓存

    Mybatis 动态sql的编写与开启二级缓存

    二级缓存是Mapper级别的缓存,多个SqlSession去操作同一个Mapper中的SQL语句,则这些SqlSession可以共享二级缓存,即二级缓存是跨SqlSession的,这篇文章主要介绍了Mybatis 动态sql的编写|开启二级缓存,需要的朋友可以参考下
    2023-02-02
  • Mac下设置Java默认版本的方法

    Mac下设置Java默认版本的方法

    今天工作的时候发现了一个错误,提示java版本太低,无法启动!想起自己装过高版本的Java,但是却没有默认启动,从网上找了一些资料,整理下现在分享给大家,有需要的可以参考借鉴。
    2016-10-10
  • 简述springboot及springboot cloud环境搭建

    简述springboot及springboot cloud环境搭建

    这篇文章主要介绍了简述springboot及springboot cloud环境搭建的方法,包括spring boot 基础应用环境搭建,需要的朋友可以参考下
    2017-07-07
  • SpringBoot Admin 使用指南(推荐)

    SpringBoot Admin 使用指南(推荐)

    这篇文章主要介绍了SpringBoot Admin 使用指南(推荐),Spring Boot Admin 是一个管理和监控你的 Spring Boot 应用程序的应用程序,非常具有实用价值,需要的朋友可以参考下
    2018-01-01
  • 一篇文章带你深入了解Java基础(2)

    一篇文章带你深入了解Java基础(2)

    这篇文章主要给大家介绍了关于Java中方法使用的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-08-08
  • Spring Boot学习入门之表单验证

    Spring Boot学习入门之表单验证

    表单验证主要是用来防范小白搞乱网站和一些低级的黑客技术。Spring Boot可以使用注解 @Valid 进行表单验证。下面这篇文章主要给大家介绍了关于Spring Boot学习入门之表单验证的相关资料,需要的朋友可以参考借鉴,下面来一起看看吧。
    2017-09-09
  • java获取当前日期和时间的二种方法分享

    java获取当前日期和时间的二种方法分享

    这篇文章主要介绍了java获取当前日期和时间的二种方法,需要的朋友可以参考下
    2014-03-03

最新评论