NullPointException 堆栈信息丢失

在生产环境JRE 运行在server 模式下, 从日志上看大量的NullPointException日志打印时,没有堆栈信息输出。查了一下,JIT编译会对某些异常如果大量的抛出时,会进行优化,删除堆栈信息。

通过下面的代码可以重现问题


public class NullPointExceptionCountMain {
        public static void main(String[] args) {
            while (i <= 200000) {
                try {
                    Long l = null;
                    l.toString();
                } catch (Exception e) {
                    if (e.getStackTrace().length == 0) {
                        System.out.println("count is " + i);
                        break;
                    }
                }
                i++;
            }
        }
}

client 模式下运行,异常堆栈正常

java -classpath . NullPointExceptionCountMain

server 模式下运行,问题就重现出来。

java -server -classpath . NullPointExceptionCountMain

解决方案:

  • -XX:-OmitStackTraceInFastThrow 关闭异常堆栈优化

        java -XX:-OmitStackTraceInFastThrow -classpath . NullPointExceptionCountMain
    

OmitStackTraceInFastThrow官方的说明

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.  
  • -Xint 以解释模式执行

        java -Xint -classpath . NullPointExceptionCountMain
    

注意的是,在解释模式 (interpreted mode) 下,-Xint 标记会强制 JVM 执行所有的字节码,当然这会降低运行速度,通常低 10 倍或更多。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容