Search code examples
javamemoryjvm-hotspot

Could a JVM possibly optimize the memory required for references to null, the instance of null type?


Good afternoon all,

I have a class which looks like this:

public class Grapheme {
    public Grapheme(int[] code_points) {
        this.code_points = code_points;
    }
    int[] code_points;
}

From the link provided by bdonlan below, I understand that typically a Grapheme object would require 8 bytes for object header, 4 bytes for the variable code_points (whose type is reference), and 4 bytes of padding.

So if I create an instance of Grapheme using the code new Grapheme(null), that instance of Grapheme would typically require a total of 16 bytes. Since whether or not it is 16 bytes is implementation specific, from here on I'll refer to this number as x bytes.

Basically I was wondering if I create n number of Graphemes, passing null into the constructor Grapheme(int[]) for all of them, and store those Graphemes into an array of length n,

Will the total memory required by the runtime (to store the Grapheme instances) be strictly n * x bytes?

Or is there any chance that the JVM could try and do some magic optimizations such that the memory required is below n * x bytes ?


Solution

  • No. The size of an object is fixed. Consider - if the JVM did pack your Graphemes into an array with no space between them, what happens if some code changes the value of code_points later? It'd have to move all the other Graphemes around, and rewrite any pointers to any of them. This would be a HUGE performance hit (you'd probably need to perform a full GC to rewrite all those pointers...), and be totally inscrutable to the programmer trying to figure out why a simple assignment was so slow. So the JVM does no optimizations of this sort.

    Also note that your overhead estimates are a bit off. According to this page, objects have an overhead of 8 bytes, plus the space for any internal fields, for 12 bytes. This is then rounded up to a multiple of 8 bytes - so your Grapheme object here would be 16 bytes in total on a 32-bit platform and the Hotspot JVM. Any pointers to the Grapheme object will take additional space (probably 4 bytes each). Objects do not need space for their own address per se; that memory is owned by something else (eg, a stack frame, or another object).