Java踩知-NPE异常无堆栈

1、背景

在生产环境中,开发人员多少都在生产环境中遇到过NPE异常明明printStackTrace 了,堆栈信息只有令人绝望的的”null“ 4个字母。但其实往前翻一番日志,还是会找到包含具体NPE 位置的堆栈信息,但是为什么有时候有NPE位置信息,有时候没有呢?

又有没有解决的必要性呢?

2、原因、方案

简书:https://www.jianshu.com/p/03d41fb71987

Stack Overflow:https://stackoverflow.com/questions/2411487/nullpointerexception-in-java-with-no-stacktrace

We have seen this same behavior in the past.It turned out that, for some crazy reason,if a NullPointerException occurred at the same place in the code multiple times, after a while using Log.error(String, Throwable) would stop including full stack traces.

Try looking further back in your log. You may find the culprit.

2.1、原因

jvm针对频繁出现的异常做了优化,可以在出现异常的时候快速抛出,不需要打印出整个调用链,这样可以节省异常堆栈的内存分配。

2.2、解决方案

既然jvm针对这个做了优化,那肯定有禁用这个优化的方法,那就是-XX:-OmitStackTraceInFastThrow参数(禁用快抛,即展示完整异常)

3、多少次异常后不打印具体异常信息?

3.1、异常类

public class WithNPE extends Thread {

    private int count;

    public WithNPE(Integer count) {
        this.count = count;
    }

    @Override
    public void run() {
        try {
            String str = null;
            // 制造空指针NPE
            System.out.println(str.length());
        } catch (Throwable e) {
            if (e.getStackTrace().length == 0) {
                FastThrowMain.countDown();
                System.out.println();
                System.out.println();
                System.out.printf("count:" + count);
            }
        }
    }
}

3.2、测试主类

public class FastThrowMain {
    private static volatile AtomicInteger count = new AtomicInteger(0);
    private static CountDownLatch countDownLatch = new CountDownLatch(1);

    public static void main(String[] args) throws InterruptedException {
        ExecutorService executorService = Executors.newFixedThreadPool(1);
        for (int i = 0; i < 8000; i++) {
            WithNPE withNPE = new WithNPE(count.getAndIncrement());
            executorService.execute(withNPE);
        }
        countDownLatch.await();
        executorService.shutdown();
    }

    public static void countDown() {
        countDownLatch.countDown();
    }
}

3.2、运行5次结果

count:6865
count:6913
count:6862
count:6889
count:6885

3.3、结论

jvm优化,不打印异常堆栈信息的次数是多少呢?

笔者环境:jdk1.8.0_77
测试结果为6800-7000 之间

对于线上环境,这个数值还是挺容易达到的。

4、处理建议

虽然使用-XX:-OmitStackTraceInFastThrow 可以禁用jvm 优化,每次异常都会打印完整堆栈信息,方便直接定位异常位置。但是笔者还是建议保持这个优化,因为打印堆栈信息需要遍历整个线程堆栈,是比较耗费性能的。

当线上发现NPE没有具体异常信息时可以尝试向前找找日志。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,053评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,527评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,779评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,685评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,699评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,609评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,989评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,654评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,890评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,634评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,716评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,394评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,976评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,950评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,191评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,849评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,458评论 2 342

推荐阅读更多精彩内容

  • 一、编程规约 (一)命名规约 【强制】 代码中的命名均不能以下划线或美元符号开始,也不能以下划线或美元符号结束。反...
    喝咖啡的蚂蚁阅读 1,475评论 0 2
  • 阿里巴巴 JAVA 开发手册 1 / 32 Java 开发手册 版本号 制定团队 更新日期 备 注 1.0.0 阿...
    糖宝_阅读 7,492评论 0 5
  • 在 Java 中处理异常并不是一个简单的事情。不仅仅初学者很难理解,即使一些有经验的开发者也需要花费很多时间来思考...
    JourWon阅读 950评论 0 2
  • 命名风格 【强制】代码中的命名均不能以下划线或美元符号开始,也不能以下划线或美元符号结束 【强制】代码中的命名严禁...
    云A00000阅读 3,579评论 0 0
  • 养生不排寒,一切都白谈! 万病由寒起,寒从脚根生! 树老根先死,人老脚先衰! 女人不排寒,定有小肚腩! 女人不排寒...
    小儿推拿罗清红阅读 300评论 0 0