How is null represented in memory in java [duplica

2020-06-18 03:47发布

问题:

This question already has answers here:
Closed 7 years ago.

Possible Duplicate:
What exactly is null in Java memory

Does anyone know how a null value is represented in the memory for an object or anything. In dot net it is represented by null indicator Boolean value and value of the corresponding type (Refer here). So does any one know how it is done in java ??

回答1:

From the JVM specification, section 2.4:

The Java virtual machine specification does not mandate a concrete value encoding null.

So it could be anything, but it's very likely to be a reference value which is all zeroes. References themselves can be simple pointers (i.e. just a virtual address in the same way as a native pointer, of the appropriate size for the architecture) but again don't have to be. Some JVMs have very smart ways of handling references - for example, Hotspot is able to use 32-bit values for references in many situations, even when running in an x64 process.



回答2:

In theory it is a JVM secret, in practice it is 0 (0x00000000) on 32-bin VM. If you use Oracle JVM you can use sun.misc.Unsafe, which can read memory content at any address, to verify.

public class Test {
    int i1 = 100;
    String s = null;
    int i2 = 200;

    public static void main(String[] args) throws Exception {
        Test test = new Test();
        System.out.println(getInt(test, "i1"));
        System.out.println(getInt(test, "s"));
        System.out.println(getInt(test, "i2"));
    }

    static int getInt(Test test, String name) throws Exception {
        Unsafe u = getUnsafe();
        long offset = u.objectFieldOffset(Test.class.getDeclaredField(name));
        return u.getInt(test, offset);
    }

    static Unsafe getUnsafe() throws Exception {
        Field f = Unsafe.class.getDeclaredField("theUnsafe");
        f.setAccessible(true);
        return (Unsafe) f.get(null);
    }
}

output

100
0
200


回答3:

No memory should be allocated for the null itself, because null is not actually a valid object instance. It is simply a placeholder that indicates that the object reference is not currently referring to an object.

When you do something like:

String str = null;

The only thing allocated is a reference to a string (this is analogous to a string-pointer in languages which contain pointer-types). This reference is a 32 or 64 bit variable (depending upon your hardware architecture and Java version) which resides on the stack (probably, depending upon the exact context in which your declaration is placed).



回答4:

The exact representation is not specified but I would assume it is just 0x0 like it is on other C like languages. It is a special value which cannot occur otherwise, not an additional field or extra piece of information.

Note: when you have a String it is a reference not an Object. This 4-byte value can refer to an object or in the case of null is a value which is not a valid object.

BTW: Most 64-bit JVMs use 32-bit references unless the heap is 32 GB or more. This is possible in an OpenJDK JVM as all objects are 8 byte (or 16 byte) aligned. As the lower 3 or 4 bits are always 0 they don't need to be stored expanding the address range by 8x or 16x the typical 4 GB range.