Java Null Exception 没有堆栈的问题解决。

1问题  NULL Exception 的堆栈信息,不是总是有完整的堆栈信息,有的时候没有,如何解决呢?见下面代码。

public class NullExceptionTest {

    static final Logger logger = Logger.getLogger(FileUpload.class);


    public static void main(String[] args) {
        int youcount = 0;
        int wucount = 0;
        for(int i = 0; i < 100000; i++){
            String a = null;
            try{
                a.toLowerCase();
            }   catch (Exception e){
                if(e.getStackTrace().length == 0) {
                    System.out.println(e.getStackTrace().length);
                    System.out.println(e.getStackTrace());
                    wucount++;
                }   else{
                    youcount++;

                }
            }
        }
        System.out.println("youcount"+youcount);
        System.out.println("wucount"+wucount);

    }
}

2 问题解决 参考 http://jawspeak.com/2010/05/26/hotspot-caused-exceptions-to-lose-their-stack-traces-in-production-and-the-fix/

重点是 这句号

since our isolated example code above indicated that initial exceptions would throw with the full stack trace, we went back into older logs and grepped. 第一次报Null exceptions一定是有完成的堆栈信息的,找到就行了。

Today I was working with Kumar and Elian where we encountered production logs with dozens of NullPointerExceptions with no stack trace. We identified that the JIT compiler will optimize away stack traces in certain exceptions if they happen enough. The code below reproduces it. We are on jdk 1.6 (I don’t remember the minor version now).

Run it as follows and the issue will appear (the stack trace length changes from 2 to 0):
javac NpeThief.java && java -classpath . NpeThief
javac NpeThief.java && java -server -classpath . NpeThief

How to fix it? The following options resolve it and it stays at 2, never going to 0 as length of NPE’s stack trace:
javac NpeThief.java && java -XX:-OmitStackTraceInFastThrow -server -classpath . NpeThief
javac NpeThief.java && java -XX:-OmitStackTraceInFastThrow -classpath . NpeThief
javac NpeThief.java && java -Xint -classpath . NpeThief
javac NpeThief.java && java -Xint -server -classpath . NpeThief

So the solution is to start with -XX:-OmitStackTraceInFastThrow argument to java which instructs the JIT to remove this optimization [1,2], or operate in interpreted only mode [3]. What is going on? [2]

The JVM flag -XX:-OmitStackTraceInFastThrow disables the performance optimization of the JVM for this use case. If this flag is set, the stacktrace will be available. (editor: or if the -Xint is set).

“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.”http://java.sun.com/j2se/1.5.0/relnotes.html

How does this impact performance? I did extremely naive timing and time java [args] -classpath . NpeThief. It behaved as expected, with interpreted the slowest. Is that the solution?

No. We weren’t going to change production JVM options to resolve this, insteadsince our isolated example code above indicated that initial exceptions would throw with the full stack trace, we went back into older logs and grepped. Sure enough, right after we deployed there were exceptions appearing with the full stack trace. That gives us enough information where we can identify and fix the bug.

Notes:
[1] Related sun bug 4292742 NullPointerException with no stack trace
[2] Helpful StackOverflow discussion of NullPointerException missing stack traces
[3] -Xint: Operate in interpreted-only mode. Compilation to native code is disabled, and all bytecodes are executed by the interpreter. The performance benefits offered by the Java HotSpot VMs’ adaptive compiler will not be present in this mode.


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
根据提供的引用内容,出现"Reason: null; nested exception is java.lang.NullPointerException"的原因是空指针异常(NullPointerException)。空指针异常通常发生在Java程序中,当尝试使用一个空对象的方法或属性时会抛出该异常。 以下是解决空指针异常的一些方法和步骤: 1. 检查空指针异常的堆栈跟踪:通过查看异常的堆栈跟踪,可以确定哪个方法或行导致了空指针异常。堆栈跟踪将指出出现异常的代码行。 2. 检查空引用:确保在使用对象之前,对对象进行了正确的初始化。如果对象为空,尝试使用它的方法或属性将导致空指针异常。可以使用条件语句(如if语句)来检查对象是否为空,然后采取相应的措施。 3. 避免使用空对象:在编写代码时,尽量避免使用可能为空的对象。可以使用条件语句或空值检查来确保对象不为空,然后再使用它。 4. 使用try-catch块处理异常:可以使用try-catch块来捕获空指针异常,并采取适当的措施来处理异常。在catch块中,可以记录异常信息、打印错误消息或执行其他必要的操作。 5. 使用断言:可以使用断言来验证对象是否为空。断言是一种用于调试和测试的机制,可以在代码中插入断言语句来检查条件是否为真。如果断言失败,将抛出AssertionError异常。 6. 使用日志记录:可以使用日志记录框架(如log4j或java.util.logging)来记录空指针异常和其他异常。日志记录可以帮助定位和调试问题。 请注意,以上方法和步骤是一般性的解决方案,具体的解决方法可能因情况而异。根据具体的代码和异常信息,可能需要采取其他措施来解决空指针异常。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值