Search code examples
javanullpointerexceptioncompiler-constructionjvm

How does the JVM know when to throw a NullPointerException


How does the Java Virtual Machine know when to throw a NullPointerException? Does it check before every method I call on a an object if the object is null to check if it has to throw a NullPointerException? And if so, isnt this realy slow?


Solution

  • There are two approaches that the JVM could use to "detect" the nulls.

    • The JVM could test explicitly the value of the reference before using it. This represents an overhead, but the JIT compiler could optimize away some of the null tests. For example:

      1. A method call on this it cannot give an NPE.
      2. If p is not volatile and you write this:

        if (p != null) { p.something(); }
        

        then, the implied null check in p.something() is not needed.

      3. If p is not volatile and you write this:

        p.something();
        p.somethingElse();
        

        and then the second implied null check is not needed.

      It is also worth noting that a null test could have zero performance impact on a CPU with a deep pipeline. It will depend on the localized memory access patterns, and whether the compiler / hardware is able to schedule the test instruction to overlap with (say) a memory fetch or store.

    • The JVM could implement the null check using virtual memory hardware. The JVM arranges that page zero in its virtual address space is mapped to a page that is unreadable + unwriteable. Since null is represented as zero, when Java code tries to dereference null this will try to access a non-addressible page and will lead to the OS delivering a "segfault" signal to the JVM. The JVM's segfault signal handler could trap this, figure out where the code was executing, and create and throw an NPE on the stack of the appropriate thread.

      This is complicated and rather expensive. However, the expense does not matter provided that NPEs occur sufficiently rarely in the application.