寻找缺少的堆栈跟踪

我们最近在博客中发表的一篇评论带回了有关特定体验的一些回忆。 我希望我没有经历过的那种经历。 在我们创建Plumbr之前很长时间,我正在调试一个应用程序,该应用程序每次在蓝月亮时都会给我一个例外。 详细程度令人震惊:

java.lang.NullPointerException

就是这样–没有可使用的stacktrace。 而且该应用程序由一个真正邪恶的系统管理员保护着,他不会让我在部署后100码之内。 因此,为所有通宵人员准备了一个阶段,他们试图了解导致错误的原因。 我敢打赌,大多数读者都知道我在这里说什么。 第一个嫌疑犯是显而易见的。 暑期实习生从未真正获得过异常处理,并且可以轻松地吞下异常,而无需重新抛出或正确记录日志。 所以我期望在代码中的某处找到这样的东西:

System.out.println(e);

但是,无论我对源代码进行多彻底的检查 ,都找不到类似这种粗心大意的东西。 从第二天起,除了每隔几个小时接一个电话并提供“进度报告”,我就没有多少回忆。 不幸的是,进展遥遥无期。 除非我想尽一切努力对生产进行大量更新,以使他们对可能的原因有一些更有意义的尝试。 但是我确实记得当我开始怀疑我一直认为不可能的事情时,我对Java的信念。 也就是说,Java能够从字面上吞噬您的Exception堆栈跟踪。 实际上,JIT可以并且将会做到。 需要证明吗? 运行以下代码:

for (int i = 0; i < 100_000; i++) {
	try {
		args[0].toString();
	} catch (Exception e) {
		if (e.getStackTrace().length == 0) {
			System.out.format("Java ate my stacktrace after iteration #%d %n", i);
			break;
		}
	}
}

在装有最新稳定JDK 7热点的MB Pro中,异常堆栈跟踪在迭代#12,288中被吞噬。 但是为什么在地球上会发生这种情况,又如何避免呢? 简单的答案是,它是运行时期间应用的JIT优化之一。 正如我们最近发表的一篇文章所描述的那样,创建Exceptions 非常昂贵 。 因此,出于性能目的,当JIT发现多次抛出异常时,可以重新编译代码。 重新编译后,编译器可以使用不提供堆栈跟踪的预分配异常来选择更快的策略。 希望你们中的绝大多数将永远不必处理这种情况。 毕竟,当以触发JIT切换到预分配的异常的速度创建异常时,您肯定在做其他错误。 毕竟,仅在例外情况下才应发生例外。 但是对于那些这样做的人,解决方案很简单。 您可以通过将-XX:-OmitStackTraceInFastThrow添加到JVM启动参数来禁用预分配的异常。 我也是,在下一次JVM重新启动后找到了罪魁祸首。


翻译自: https://www.javacodegeeks.com/2013/09/on-a-quest-for-missing-stacktraces.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值