前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >定位生产问题时,异常堆栈莫名丢了,何解?

定位生产问题时,异常堆栈莫名丢了,何解?

作者头像
一猿小讲
发布2020-08-18 16:04:55
1.2K0
发布2020-08-18 16:04:55
举报
文章被收录于专栏:一猿小讲一猿小讲

今天分享的这个知识有点冷,相信很多 Java 程序员很少遇到,废话不多说,直接进入排查问题的真实讨论现场。

小 猿:有个 NPE 异常,有空帮忙看看是哪里出的?

架构狮:我没有看到空指针堆栈啊!?

小 猿:有堆栈我就自己找问题了,就不劳驾您老啦(捂嘴笑)。

架构狮:是不是 NPE 报了好多次?

小 猿:是。

架构狮:一猜就是,因为只有报了很多次,Java 才会自动不打印异常堆栈信息(言外之意:报了多了 java 会省略的),那就找找最开始报异常的日志,肯定会有堆栈信息的(哈哈,心里有谱啦),这种机制叫做 fast throw。

1

异常堆栈信息丢了?

只见 Java 攻城狮小猿傻傻的盯着业务日志,一脸呆萌... ...

代码语言:javascript
复制
[2020-08-15 00:00:00]: 668812118 Thread-8 [ERROR] payService:java.lang.NullPointerException

与其傻傻迷思,不妨直接来个现场说法,talk is cheap,show me the code,直接上代码。

代码语言:javascript
复制
/**
 * Fast Throw 知识点分享
 * @author 一猿小讲
 */
public class NPETest {
    public static void main(String[] args) {
        String msg = null;
        for (int i = 0; i < 1000000; i++) {
            try {
                // msg 为空,会出现空指针异常
                System.out.println(msg.length());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

程序刚开始跑的时候,程序输出是下面这样子的。

代码语言:javascript
复制
java.lang.NullPointerException
  at NPETest.main(NPETest.java:11)
... ... 
java.lang.NullPointerException
  at NPETest.main(NPETest.java:11)

一会儿的功夫,输出却变成下面这个样子,异常堆栈确实丢了。

代码语言:javascript
复制
java.lang.NullPointerException
java.lang.NullPointerException
java.lang.NullPointerException
java.lang.NullPointerException

架构狮:惊奇不?有没有匪夷所思。

小 猿:何解?

架构狮:这种现象就叫做 fast throw,是 Java 虚拟机的一个优化,如果发现代码同一个位置频繁抛出同一类型的异常时,异常堆栈信息就会被清空,那么速度就会非常快,就不用再额外分配内存。

到这儿,Java 攻城狮小猿,点了一根香烟,感觉受益颇深,不过却又陷入了沉思。

2

Fast Throw 深入一点,又何妨?

思考一:查问题也太不方面了,如何让异常堆栈信息展示呢?

首先要清楚,JVM 会默认开启 Fast Throw 优化。如果想关闭这个优化,通过配置 -XX:-OmitStackTraceInFastThrow 就可以。

接下来还是跑上面 NPETest 的例子,配置 VM 参数,一起操作一把。

IDEA 运行时指定参数:-XX:-OmitStackTraceInFastThrow。

控制台运行时指定参数:

代码语言:javascript
复制
java -XX:-OmitStackTraceInFastThrow NPETest

效果很明显,异常堆栈信息一直坚挺到最后:

代码语言:javascript
复制
... ...
java.lang.NullPointerException
        at NPETest.main(NPETest.java:11)
java.lang.NullPointerException
        at NPETest.main(NPETest.java:11)
java.lang.NullPointerException
        at NPETest.main(NPETest.java:11)

话又说来,如何再开启 fast throw 优化呢?

代码语言:javascript
复制
方式一:默认就是开启优化;
方式二:-XX:+OmitStackTraceInFastThrow

思考二:除了 NPE 异常,JVM 开启 fast throw 优化的异常还有哪些?

  • ArithmeticException
  • ArrayIndexOutOfBoundsException
  • ArrayStoreException
  • ClassCastException

烟味灭,酒过半,Java 攻城狮小猿彻底掌握了技巧,嘴角洋溢着笑容,此番操作不但解决了生产问题,而且又 get 一装逼技能... ...

3

寄语写最后

本次,主要对小猿在排查生产上遇到的一个匪夷所思的问题,作为基础进行展开,简单对 JVM 特定类型的异常的 fast throw 优化进行了解,希望对大家有帮助。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-08-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 一猿小讲 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档