log exception without trace 异常信息无堆栈

1.可用率报警后查看异常日志,发现打印的异常信息,没有堆栈信息

2.检查日志打印格式,是按照异常对象打印的,是正确的打印方式,代码如下

       try {
            ......
        } catch (Throwable t){
            LOGGER.error(ThreadLocalUtil.get() + "批量获取距离异常:", t);
            ......
        } finally {
            ThreadLocalUtil.clear();
        }

3.继续查询相关资料,发现是jvm做的优化

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.

虚拟机打印堆栈超过一定次数以后,会关闭掉异常堆栈的打印,通过-XX:-OmitStackTraceInFastThrow 参数可禁用掉该优化

4.测试复现验证,代码如下

public class ExceptionTraceTest {
    public static void main(String[] args) {
        int i =0;
        String test = null;
        while (true){
            try {
                test.length();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

最开始的输出,异常信息中有堆栈信息

java.lang.NullPointerException
    at com.shuaisam.reboot.jvm.param.ExceptionTraceTest.main(ExceptionTraceTest.java:14)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
java.lang.NullPointerException
    at com.shuaisam.reboot.jvm.param.ExceptionTraceTest.main(ExceptionTraceTest.java:14)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)

输出一定数量以后,异常信息中只有异常message信息,没有了堆栈

java.lang.NullPointerException
java.lang.NullPointerException
java.lang.NullPointerException
java.lang.NullPointerException
java.lang.NullPointerException
java.lang.NullPointerException
java.lang.NullPointerException
java.lang.NullPointerException
java.lang.NullPointerException
java.lang.NullPointerException
java.lang.NullPointerException
java.lang.NullPointerException
java.lang.NullPointerException

5.加入jvm参数 -XX:-OmitStackTraceInFastThrow 重新运行代码

继续运行,一段时间后异常仍然全部打印出了堆栈,现象符合预期

6.解决办法

  • 历史日志还在的话,查看历史日志异常堆栈
  • 重新启动服务器,再观察日志
  • 设置JVM参数,暂时禁止掉这个优化选项: -XX:-OmitStackTraceInFastThrow

7.参考资料

https://stackoverflow.com/questions/2295015/log4j-not-printing-the-stacktrace-for-exceptions

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • Java 应用性能优化是一个老生常谈的话题,典型的性能问题如页面响应慢、接口超时,服务器负载高、并发数低,数据库频...
    Rick617阅读 12,146评论 1 9
  • 1、指定垃圾收集器 -XX:+UseSerialGC 指定使用串行垃圾收集器,新生代及老年代都是串行收集,在大堆或...
    dayspring阅读 7,595评论 0 4
  • 1、指定垃圾收集器 -XX:+UseSerialGC 指定使用串行垃圾收集器,新生代及老年代都是串行收集,在大堆或...
    yangjingqiang阅读 4,320评论 0 0
  • 这篇文章是我之前翻阅了不少的书籍以及从网络上收集的一些资料的整理,因此不免有一些不准确的地方,同时不同JDK版本的...
    高广超阅读 15,973评论 3 83
  • 壹 那天文都考研,到我们学校来进行宣传,需要会场分发资料的工作人员,而我恰巧有时间,于是就去了。 那天来负责宣传的...
    懒癌先生_阅读 4,468评论 0 6

友情链接更多精彩内容