I'm currently profiling some Java application using the Eclipse Memory Analyzer plugin (using a standard jconsole hprof dump), and I noticed some strange results on computed object size:
private static class B1 extends B {
} // 16 bytes
private static class B2 extends B {
boolean d1;
boolean d2;
boolean d3;
boolean d4;
} // also 16 bytes!
private static class B3 extends B {
boolean d1;
boolean d2;
boolean d3;
boolean d4;
boolean d5;
} // 24 bytes
Apparently the first 4 booleans are somehow stuffed away in the object header, how is this?
Note: Tested with Oracle JDK1.7 and JDK1.8, 64 bits, running on Linux x64.
There is no optimization going on; the object header is commonly 8 or 12 bytes large, depending on VM and mode (Compressed OOPS on/off). Also commonly the memory granularity is 8 bytes (Object sizes in memory must always be a multiple of the granularity).
Your results clearly indicate that your VM uses a 12 byte header; so there is room for 4 bytes due to granularity without growing the obbject memory footprint. The booleans are commonly represented as bytes; so adding a 5th in your case requires 17 bytes (12 header + 5 bytes) rounded to next granularity 8 boundary gives 24 bytes.
Within 64-bit HotSpot JVM with CompressedOops
markWord
+ 4 byte instanceKlass
referenceboolean
field occupy 1 byteThat is
align8(8 + 4) = 16 bytes
align8(8 + 4 + 4*1) = 16 bytes
align8(8 + 4 + 5*1) = align8(17) = 24 bytes
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With