最近在项目中遇到一个现象,系统抛出NullPointerException。正常情况,这种问题非常好定位,根据调用栈看看是哪一行空指针就好。 不过这次比较诡异,跑异常的地方没有打出堆栈。 "java.lang.NullPointerException: null" 这是唯一的信息。
因为这是个netty项目,一开始以为是用了“io.netty.util.internal.ThrowableUtil.unknownStackTrace” 这个方法来创建异常,这个方法会把stack信息抹掉。项目中搜索相关代码,没有搜索到用这个方法创建的NullPointerException。
public static <T extends Throwable> T unknownStackTrace(T cause, Class<?> clazz, String method) {
cause.setStackTrace(new StackTraceElement[] { new StackTraceElement(clazz.getName(), method, null, -1)});
return cause;
}
同事google发现jvm有这方面的优化,称为fast throw。当一个异常重复抛出达到一定次数时,jvm就会抛出预先创建好的异常对象。这样做的好处主要就是不用收集调用栈,也不用申请内存。当然给用户就带来困惑,给问题定位带来一定的麻烦。jvm也给我们提供了配置去关闭这个特性: -XX:-OmitStackTraceInFastThrow
最后,一般情况不要关闭这个特性。如果遇到了不打栈的情况再考虑加上。
本文探讨了在Netty项目中遇到的NullPointerException异常处理问题,深入解析了JVM的FastThrow优化机制,如何在异常重复抛出时使用预创建的异常对象以提高效率,以及如何通过JVM参数调整来解决异常定位难题。
4036

被折叠的 条评论
为什么被折叠?



