sizeof(Object): how much memory objects take on JVMs and when this may matter

82
sizeof(new Object()) how much memory objects take on JVMs . . . and when this may matter Dawid Weiss Carrot Search s.c. Poznań, May 2012

description

How large (physically) are objects in Java? How are they stored? Can we hexdump an object in Java? All this and more.Poznan JUG, May 2012.

Transcript of sizeof(Object): how much memory objects take on JVMs and when this may matter

Page 1: sizeof(Object): how much memory objects take on JVMs and when this may matter

sizeof(newObject())howmuchmemory objects take on JVMs.. .and when this maymatter

DawidWeissCarrot Search s.c.

Poznań, May 2012

Page 2: sizeof(Object): how much memory objects take on JVMs and when this may matter

DawidWeiss

Likes coding10 years assembly only

Likes researchFormer academic. PhD in IR.

Likes open sourceCarrot2, HPPC, Lucene PMC, . . .

Likes industryCarrot Search s.c.

.

.

.

.

.

.

. .

Page 3: sizeof(Object): how much memory objects take on JVMs and when this may matter

Memory

Page 4: sizeof(Object): how much memory objects take on JVMs and when this may matter

A byte

8 bits 7 6 5 4 3 2 1 0

2 nibbles hi lo

1 byte byte

Page 5: sizeof(Object): how much memory objects take on JVMs and when this may matter

A byte (concrete value)

8 bits 1 1 1 0 0 0 1 1

2 nibbles E 3

1 byte E3

Page 6: sizeof(Object): how much memory objects take on JVMs and when this may matter

Memory (*)A linear sequence of bytes, each one at a certain offset(address), starting with 0.

Page 7: sizeof(Object): how much memory objects take on JVMs and when this may matter

hexdumpA textual dump of bytes frommemory or le. May beaccompanied by (US-ASCII) character codes.

> hexdump -C jug.png

00000000 89 50 4e 47 0d 0a 1a 0a 00 00 00 0d 49 48 44 52 |.PNG........IHDR|00000010 00 00 01 30 00 00 00 96 08 02 00 00 00 d6 ab 43 |...0...........C|00000020 e3 00 00 00 01 73 52 47 42 00 ae ce 1c e9 00 00 |.....sRGB.......|00000030 2a a7 49 44 41 54 78 5e ed 5d 09 7c 14 45 d6 9f |*.IDATxˆ.].|.E..|00000040 7b 26 c9 24 90 20 09 24 a0 2e 09 02 2a e7 ba 20 |{&.$. .$....*.. |00000050 87 0a 2a 8a 28 ae 72 e8 ae 1c a2 0b 0a 22 0a 0a |..*.(.r......"..|...

Page 8: sizeof(Object): how much memory objects take on JVMs and when this may matter

hexdumpA textual dump of bytes frommemory or le. May beaccompanied by (US-ASCII) character codes.

> hexdump -C jug.png

00000000 89 50 4e 47 0d 0a 1a 0a 00 00 00 0d 49 48 44 52 |.PNG........IHDR|00000010 00 00 01 30 00 00 00 96 08 02 00 00 00 d6 ab 43 |...0...........C|00000020 e3 00 00 00 01 73 52 47 42 00 ae ce 1c e9 00 00 |.....sRGB.......|00000030 2a a7 49 44 41 54 78 5e ed 5d 09 7c 14 45 d6 9f |*.IDATxˆ.].|.E..|00000040 7b 26 c9 24 90 20 09 24 a0 2e 09 02 2a e7 ba 20 |{&.$. .$....*.. |00000050 87 0a 2a 8a 28 ae 72 e8 ae 1c a2 0b 0a 22 0a 0a |..*.(.r......"..|...

Page 9: sizeof(Object): how much memory objects take on JVMs and when this may matter

Types in Java

Page 10: sizeof(Object): how much memory objects take on JVMs and when this may matter

Data types in Java

Primitive types (non-objects).long, double, int, . . .

Objects.Anything that requires new.

Single-dimensional arrays of the above.Fixed size, max. 2 147 483648 elements.

Page 11: sizeof(Object): how much memory objects take on JVMs and when this may matter

Primitives

type required bytes

byte 1boolean 1char 2short 2float 4int 4double 8long 8

Page 12: sizeof(Object): how much memory objects take on JVMs and when this may matter

Objectspublic class MyClass {public boolean field1;public int field2;public Object field3;

}

What's sizeof(newMyClass())?This is considered VM implementation and hardware detail!

(But sometimes we'd like to know.)

Page 13: sizeof(Object): how much memory objects take on JVMs and when this may matter

Objectspublic class MyClass {public boolean field1;public int field2;public Object field3;

}

What's sizeof(newMyClass())?

This is considered VM implementation and hardware detail!

(But sometimes we'd like to know.)

Page 14: sizeof(Object): how much memory objects take on JVMs and when this may matter

Objectspublic class MyClass {public boolean field1;public int field2;public Object field3;

}

What's sizeof(newMyClass())?This is considered VM implementation and hardware detail!

(But sometimes we'd like to know.)

Page 15: sizeof(Object): how much memory objects take on JVMs and when this may matter

Access to low-level Java

Page 16: sizeof(Object): how much memory objects take on JVMs and when this may matter

Low-level Java

Read the VM source code.If available (openjdk). Requires time.

Instrumentation (agent).Provides getObjectSize estimate. Requires an agent at startup.

sun.misc.UnsafeSUN's box of "only we can touch it" toys. Inherited bymost other vendors (be-cause of sublicensing, for compatibility?).

Page 17: sizeof(Object): how much memory objects take on JVMs and when this may matter

Hexdumping Java objects

Page 18: sizeof(Object): how much memory objects take on JVMs and when this may matter

WARN: any of the code shown further on relies onundocumented and unspeci ed JVM internals andmay not

work or even compile.

Page 19: sizeof(Object): how much memory objects take on JVMs and when this may matter

Acquiring Unsafe instance like this:

sun.misc.Unsafe.getUnsafe();

java.lang.SecurityException: Unsafeat sun.misc.Unsafe.getUnsafe(Unsafe.java:68)at com.carrotsearch.sizeofexamples.UnsafeAccess.unsafe(UnsafeAccess.java:8)...

. . . is a no-no. But we can access the static singleton:Class<?> unsafeClass = sun.misc.Unsafe.class;Field fld = unsafeClass.getDeclaredField("theUnsafe");fld.setAccessible(true);return (sun.misc.Unsafe) fld.get(null);

Page 20: sizeof(Object): how much memory objects take on JVMs and when this may matter

Acquiring Unsafe instance like this:

sun.misc.Unsafe.getUnsafe();

java.lang.SecurityException: Unsafeat sun.misc.Unsafe.getUnsafe(Unsafe.java:68)at com.carrotsearch.sizeofexamples.UnsafeAccess.unsafe(UnsafeAccess.java:8)...

. . . is a no-no. But we can access the static singleton:Class<?> unsafeClass = sun.misc.Unsafe.class;Field fld = unsafeClass.getDeclaredField("theUnsafe");fld.setAccessible(true);return (sun.misc.Unsafe) fld.get(null);

Page 21: sizeof(Object): how much memory objects take on JVMs and when this may matter

Here's a snippet of Unsafe documentation:/*** Fetches a value from a given Java variable.** More specifically, fetches a field or array element within the given* object <code>o</code> at the given offset, or (if <code>o</code> is* null) from the memory address whose numerical value is the given* ...*/public native int getByte(Object o, long offset);

How about if we hexdump around and beyond object o?

Page 22: sizeof(Object): how much memory objects take on JVMs and when this may matter

Here's a snippet of Unsafe documentation:/*** Fetches a value from a given Java variable.** More specifically, fetches a field or array element within the given* object <code>o</code> at the given offset, or (if <code>o</code> is* null) from the memory address whose numerical value is the given* ...*/public native int getByte(Object o, long offset);

How about if we hexdump around and beyond object o?

Page 23: sizeof(Object): how much memory objects take on JVMs and when this may matter

public static class MyClass {public byte field;public MyClass(byte v) { field = v; }

}

@Testpublic void simpleHexDumpByte() {Object o1 = new MyClass((byte) 0xFE);Object o2 = new MyClass((byte) 0xFA);Object o3 = new MyClass((byte) 0xF0);

Unsafe unsafe = UnsafeAccess.unsafe();for (long i = 0; i < 64;) {System.out.print(String.format("%02x ", unsafe.getByte(o1, i) & 0xFF));if ((++i % 16) == 0) System.out.println();

}System.out.println();

}

-- simpleHexDumpByte(com.carrotsearch.sizeofexamples.E01_Alignments)01 00 00 00 00 00 00 00 60 a5 21 bd fe 00 00 0001 00 00 00 00 00 00 00 60 a5 21 bd fa 00 00 0001 00 00 00 00 00 00 00 60 a5 21 bd f0 00 00 0001 00 00 00 00 00 00 00 f0 28 e1 bc 28 6d 88 eb

. ...E01 Alignments

Page 24: sizeof(Object): how much memory objects take on JVMs and when this may matter

public static class MyClass {public byte field;public MyClass(byte v) { field = v; }

}

@Testpublic void simpleHexDumpByte() {Object o1 = new MyClass((byte) 0xFE);Object o2 = new MyClass((byte) 0xFA);Object o3 = new MyClass((byte) 0xF0);

Unsafe unsafe = UnsafeAccess.unsafe();for (long i = 0; i < 64;) {System.out.print(String.format("%02x ", unsafe.getByte(o1, i) & 0xFF));if ((++i % 16) == 0) System.out.println();

}System.out.println();

}

-- simpleHexDumpByte(com.carrotsearch.sizeofexamples.E01_Alignments)01 00 00 00 00 00 00 00 60 a5 21 bd fe 00 00 0001 00 00 00 00 00 00 00 60 a5 21 bd fa 00 00 0001 00 00 00 00 00 00 00 60 a5 21 bd f0 00 00 0001 00 00 00 00 00 00 00 f0 28 e1 bc 28 6d 88 eb

. ...E01 Alignments

Page 25: sizeof(Object): how much memory objects take on JVMs and when this may matter

public static class MyClassInt {public int field;public MyClassInt(int v) { field = v; }

}

@Testpublic void simpleHexDumpInt() {Object o1 = new MyClassInt(0xAABBCCDD);Object o2 = new MyClassInt(0x11223344);

Unsafe unsafe = UnsafeAccess.unsafe();for (long i = 0; i < 64;) {System.out.print(String.format("%02x ", unsafe.getByte(o1, i) & 0xFF));if ((++i % 16) == 0) System.out.println();

}System.out.println();

}

-- simpleHexDumpInt(com.carrotsearch.sizeofexamples.E01_Alignments)01 00 00 00 00 00 00 00 08 f6 21 bd dd cc bb aa01 00 00 00 00 00 00 00 08 f6 21 bd 44 33 22 1101 00 00 00 00 00 00 00 f0 df e5 bc 01 00 00 0000 00 00 00 1a 00 00 00 78 1f ed bc 70 b1 21 bd

. ...E01 Alignments

Page 26: sizeof(Object): how much memory objects take on JVMs and when this may matter

public static class MyClassInt {public int field;public MyClassInt(int v) { field = v; }

}

@Testpublic void simpleHexDumpInt() {Object o1 = new MyClassInt(0xAABBCCDD);Object o2 = new MyClassInt(0x11223344);

Unsafe unsafe = UnsafeAccess.unsafe();for (long i = 0; i < 64;) {System.out.print(String.format("%02x ", unsafe.getByte(o1, i) & 0xFF));if ((++i % 16) == 0) System.out.println();

}System.out.println();

}

-- simpleHexDumpInt(com.carrotsearch.sizeofexamples.E01_Alignments)01 00 00 00 00 00 00 00 08 f6 21 bd dd cc bb aa01 00 00 00 00 00 00 00 08 f6 21 bd 44 33 22 1101 00 00 00 00 00 00 00 f0 df e5 bc 01 00 00 0000 00 00 00 1a 00 00 00 78 1f ed bc 70 b1 21 bd

. ...E01 Alignments

Page 27: sizeof(Object): how much memory objects take on JVMs and when this may matter

Endianness (byte order)

Affects multi-byte types

Intels typically little-endian

Other processors big-endian or bi-endian

You can't assume anything about byte orderBut it is veri able -- java.nio.ByteOrder.

Page 28: sizeof(Object): how much memory objects take on JVMs and when this may matter

Conclusions so farObject o1 = new MyClass((byte) 0xFE);Object o2 = new MyClass((byte) 0xFA);Object o3 = new MyClass((byte) 0xF0);

-- simpleHexDumpByte(com.carrotsearch.sizeofexamples.E01_Alignments)01 00 00 00 00 00 00 00 60 a5 21 bd fe 00 00 0001 00 00 00 00 00 00 00 60 a5 21 bd fa 00 00 0001 00 00 00 00 00 00 00 60 a5 21 bd f0 00 00 0001 00 00 00 00 00 00 00 f0 28 e1 bc 28 6d 88 eb

What is before elds?Where does each eld start/end?What is the space "in between" objects?

Page 29: sizeof(Object): how much memory objects take on JVMs and when this may matter

Object header

Page 30: sizeof(Object): how much memory objects take on JVMs and when this may matter

openjdk/hotspot/src/share/vm/oops/oopsHierarchy.hpp

class oopDesc {// ...volatile markOop _mark;union _metadata {wideKlassOop _klass;narrowOop _compressed_klass;

} _metadata;// ...

// The markOop describes the header of an object.//// Note that the mark is not a real oop but just a word.// It is placed in the oop hierarchy for historical reasons.//// Bit-format of an object header (most significant first, big endian layout below)://// 32 bits:// --------// hash:25 ------------>| age:4 biased_lock:1 lock:2 (normal object)// JavaThread*:23 epoch:2 age:4 biased_lock:1 lock:2 (biased object)// size:32 ------------------------------------------>| (CMS free block)// PromotedObject*:29 ---------->| promo_bits:3 ----->| (CMS promoted object)//// 64 bits:// --------// unused:25 hash:31 -->| unused:1 age:4 biased_lock:1 lock:2 (normal object)// JavaThread*:54 epoch:2 unused:1 age:4 biased_lock:1 lock:2 (biased object)// PromotedObject*:61 --------------------->| promo_bits:3 ----->| (CMS promoted object)// size:64 ----------------------------------------------------->| (CMS free block)//// unused:25 hash:31 -->| cms_free:1 age:4 biased_lock:1 lock:2 (COOPs && normal object)// JavaThread*:54 epoch:2 cms_free:1 age:4 biased_lock:1 lock:2 (COOPs && biased object)// narrowOop:32 unused:24 cms_free:1 unused:4 promo_bits:3 ----->| (COOPs && CMS promoted object)// unused:21 size:35 -->| cms_free:1 unused:7 ------------------>| (COOPs && CMS free block)

Page 31: sizeof(Object): how much memory objects take on JVMs and when this may matter

openjdk/hotspot/src/share/vm/oops/oopsHierarchy.hpp

class oopDesc {// ...volatile markOop _mark;union _metadata {wideKlassOop _klass;narrowOop _compressed_klass;

} _metadata;// ...

// The markOop describes the header of an object.//// Note that the mark is not a real oop but just a word.// It is placed in the oop hierarchy for historical reasons.//// Bit-format of an object header (most significant first, big endian layout below)://// 32 bits:// --------// hash:25 ------------>| age:4 biased_lock:1 lock:2 (normal object)// JavaThread*:23 epoch:2 age:4 biased_lock:1 lock:2 (biased object)// size:32 ------------------------------------------>| (CMS free block)// PromotedObject*:29 ---------->| promo_bits:3 ----->| (CMS promoted object)//// 64 bits:// --------// unused:25 hash:31 -->| unused:1 age:4 biased_lock:1 lock:2 (normal object)// JavaThread*:54 epoch:2 unused:1 age:4 biased_lock:1 lock:2 (biased object)// PromotedObject*:61 --------------------->| promo_bits:3 ----->| (CMS promoted object)// size:64 ----------------------------------------------------->| (CMS free block)//// unused:25 hash:31 -->| cms_free:1 age:4 biased_lock:1 lock:2 (COOPs && normal object)// JavaThread*:54 epoch:2 cms_free:1 age:4 biased_lock:1 lock:2 (COOPs && biased object)// narrowOop:32 unused:24 cms_free:1 unused:4 promo_bits:3 ----->| (COOPs && CMS promoted object)// unused:21 size:35 -->| cms_free:1 unused:7 ------------------>| (COOPs && CMS free block)

Page 32: sizeof(Object): how much memory objects take on JVMs and when this may matter

openjdk/hotspot/src/share/vm/oops/oopsHierarchy.hpp

class oopDesc {// ...volatile markOop _mark;union _metadata {wideKlassOop _klass;narrowOop _compressed_klass;

} _metadata;// ...

// The markOop describes the header of an object.//// Note that the mark is not a real oop but just a word.// It is placed in the oop hierarchy for historical reasons.//// Bit-format of an object header (most significant first, big endian layout below)://// 32 bits:// --------// hash:25 ------------>| age:4 biased_lock:1 lock:2 (normal object)// JavaThread*:23 epoch:2 age:4 biased_lock:1 lock:2 (biased object)// size:32 ------------------------------------------>| (CMS free block)// PromotedObject*:29 ---------->| promo_bits:3 ----->| (CMS promoted object)//// 64 bits:// --------// unused:25 hash:31 -->| unused:1 age:4 biased_lock:1 lock:2 (normal object)// JavaThread*:54 epoch:2 unused:1 age:4 biased_lock:1 lock:2 (biased object)// PromotedObject*:61 --------------------->| promo_bits:3 ----->| (CMS promoted object)// size:64 ----------------------------------------------------->| (CMS free block)//// unused:25 hash:31 -->| cms_free:1 age:4 biased_lock:1 lock:2 (COOPs && normal object)// JavaThread*:54 epoch:2 cms_free:1 age:4 biased_lock:1 lock:2 (COOPs && biased object)// narrowOop:32 unused:24 cms_free:1 unused:4 promo_bits:3 ----->| (COOPs && CMS promoted object)// unused:21 size:35 -->| cms_free:1 unused:7 ------------------>| (COOPs && CMS free block)

Page 33: sizeof(Object): how much memory objects take on JVMs and when this may matter

Let's do this:Object o1 = new MyClass((byte) 0xfe);

System.out.println("Clean:");System.out.println(BlackMagic.objectMemoryAsString(o1));System.out.println(String.format("After identity hash: %08x", System.identityHashCode(o1)));System.out.println(BlackMagic.objectMemoryAsString(o1));

. ...E02 Header

Page 34: sizeof(Object): how much memory objects take on JVMs and when this may matter

on a 64-bit JVM:-- hashHeader(com.carrotsearch.sizeofexamples.E02_Header)Clean. [JVM: Java HotSpot(TM) 64-Bit Server VM, 21.0-b17, 1.7.0]0x0000 01 00 00 00 00 00 00 00 d8 dc 1b bd fe 00 00 00After identity hash: 7bf90a550x0000 01 55 0a f9 7b 00 00 00 d8 dc 1b bd fe 00 00 00

on a 32-bit JVM:-- hashHeader(com.carrotsearch.sizeofexamples.E02_Header)Clean. [JVM: Java HotSpot(TM) Server VM, 11.0-b16, 1.6.0_11]0x0000 01 00 00 00 90 5c 3d b2 fe 00 00 00 00 00 00 00After identity hash: 005e176f0x0000 81 b7 0b 2f 90 5c 3d b2 fe 00 00 00 00 00 00 00

(2f0bb781 >> 7 = 5e176f)

on a 64-bit JVM, full refs (-XX:-UseCompressedOops):-- hashHeader(com.carrotsearch.sizeofexamples.E02_Header)Clean. [JVM: Java HotSpot(TM) 64-Bit Server VM, 21.0-b17, 1.7.0]0x0000 01 00 00 00 00 00 00 00 d0 d6 eb a3 13 7f 00 000x0010 fe 00 00 00 00 00 00 00After identity hash: 7bf90a550x0000 01 55 0a f9 7b 00 00 00 d0 d6 eb a3 13 7f 00 000x0010 fe 00 00 00 00 00 00 00

Page 35: sizeof(Object): how much memory objects take on JVMs and when this may matter

on a 64-bit JVM:-- hashHeader(com.carrotsearch.sizeofexamples.E02_Header)Clean. [JVM: Java HotSpot(TM) 64-Bit Server VM, 21.0-b17, 1.7.0]0x0000 01 00 00 00 00 00 00 00 d8 dc 1b bd fe 00 00 00After identity hash: 7bf90a550x0000 01 55 0a f9 7b 00 00 00 d8 dc 1b bd fe 00 00 00

on a 32-bit JVM:-- hashHeader(com.carrotsearch.sizeofexamples.E02_Header)Clean. [JVM: Java HotSpot(TM) Server VM, 11.0-b16, 1.6.0_11]0x0000 01 00 00 00 90 5c 3d b2 fe 00 00 00 00 00 00 00After identity hash: 005e176f0x0000 81 b7 0b 2f 90 5c 3d b2 fe 00 00 00 00 00 00 00

(2f0bb781 >> 7 = 5e176f)

on a 64-bit JVM, full refs (-XX:-UseCompressedOops):-- hashHeader(com.carrotsearch.sizeofexamples.E02_Header)Clean. [JVM: Java HotSpot(TM) 64-Bit Server VM, 21.0-b17, 1.7.0]0x0000 01 00 00 00 00 00 00 00 d0 d6 eb a3 13 7f 00 000x0010 fe 00 00 00 00 00 00 00After identity hash: 7bf90a550x0000 01 55 0a f9 7b 00 00 00 d0 d6 eb a3 13 7f 00 000x0010 fe 00 00 00 00 00 00 00

Page 36: sizeof(Object): how much memory objects take on JVMs and when this may matter

on a 64-bit JVM:-- hashHeader(com.carrotsearch.sizeofexamples.E02_Header)Clean. [JVM: Java HotSpot(TM) 64-Bit Server VM, 21.0-b17, 1.7.0]0x0000 01 00 00 00 00 00 00 00 d8 dc 1b bd fe 00 00 00After identity hash: 7bf90a550x0000 01 55 0a f9 7b 00 00 00 d8 dc 1b bd fe 00 00 00

on a 32-bit JVM:-- hashHeader(com.carrotsearch.sizeofexamples.E02_Header)Clean. [JVM: Java HotSpot(TM) Server VM, 11.0-b16, 1.6.0_11]0x0000 01 00 00 00 90 5c 3d b2 fe 00 00 00 00 00 00 00After identity hash: 005e176f0x0000 81 b7 0b 2f 90 5c 3d b2 fe 00 00 00 00 00 00 00

(2f0bb781 >> 7 = 5e176f)

on a 64-bit JVM, full refs (-XX:-UseCompressedOops):-- hashHeader(com.carrotsearch.sizeofexamples.E02_Header)Clean. [JVM: Java HotSpot(TM) 64-Bit Server VM, 21.0-b17, 1.7.0]0x0000 01 00 00 00 00 00 00 00 d0 d6 eb a3 13 7f 00 000x0010 fe 00 00 00 00 00 00 00After identity hash: 7bf90a550x0000 01 55 0a f9 7b 00 00 00 d0 d6 eb a3 13 7f 00 000x0010 fe 00 00 00 00 00 00 00

Page 37: sizeof(Object): how much memory objects take on JVMs and when this may matter

on a 64-bit JVM:-- hashHeader(com.carrotsearch.sizeofexamples.E02_Header)Clean. [JVM: Java HotSpot(TM) 64-Bit Server VM, 21.0-b17, 1.7.0]0x0000 01 00 00 00 00 00 00 00 d8 dc 1b bd fe 00 00 00After identity hash: 7bf90a550x0000 01 55 0a f9 7b 00 00 00 d8 dc 1b bd fe 00 00 00

on a 32-bit JVM:-- hashHeader(com.carrotsearch.sizeofexamples.E02_Header)Clean. [JVM: Java HotSpot(TM) Server VM, 11.0-b16, 1.6.0_11]0x0000 01 00 00 00 90 5c 3d b2 fe 00 00 00 00 00 00 00After identity hash: 005e176f0x0000 81 b7 0b 2f 90 5c 3d b2 fe 00 00 00 00 00 00 00

(2f0bb781 >> 7 = 5e176f)

on a 64-bit JVM, full refs (-XX:-UseCompressedOops):-- hashHeader(com.carrotsearch.sizeofexamples.E02_Header)Clean. [JVM: Java HotSpot(TM) 64-Bit Server VM, 21.0-b17, 1.7.0]0x0000 01 00 00 00 00 00 00 00 d0 d6 eb a3 13 7f 00 000x0010 fe 00 00 00 00 00 00 00After identity hash: 7bf90a550x0000 01 55 0a f9 7b 00 00 00 d0 d6 eb a3 13 7f 00 000x0010 fe 00 00 00 00 00 00 00

Page 38: sizeof(Object): how much memory objects take on JVMs and when this may matter

on a 64-bit JVM:-- hashHeader(com.carrotsearch.sizeofexamples.E02_Header)Clean. [JVM: Java HotSpot(TM) 64-Bit Server VM, 21.0-b17, 1.7.0]0x0000 01 00 00 00 00 00 00 00 d8 dc 1b bd fe 00 00 00After identity hash: 7bf90a550x0000 01 55 0a f9 7b 00 00 00 d8 dc 1b bd fe 00 00 00

on a 32-bit JVM:-- hashHeader(com.carrotsearch.sizeofexamples.E02_Header)Clean. [JVM: Java HotSpot(TM) Server VM, 11.0-b16, 1.6.0_11]0x0000 01 00 00 00 90 5c 3d b2 fe 00 00 00 00 00 00 00After identity hash: 005e176f0x0000 81 b7 0b 2f 90 5c 3d b2 fe 00 00 00 00 00 00 00

(2f0bb781 >> 7 = 5e176f)

on a 64-bit JVM, full refs (-XX:-UseCompressedOops):-- hashHeader(com.carrotsearch.sizeofexamples.E02_Header)Clean. [JVM: Java HotSpot(TM) 64-Bit Server VM, 21.0-b17, 1.7.0]0x0000 01 00 00 00 00 00 00 00 d0 d6 eb a3 13 7f 00 000x0010 fe 00 00 00 00 00 00 00After identity hash: 7bf90a550x0000 01 55 0a f9 7b 00 00 00 d0 d6 eb a3 13 7f 00 000x0010 fe 00 00 00 00 00 00 00

Page 39: sizeof(Object): how much memory objects take on JVMs and when this may matter

Conclusions so far

System hashCode is not a full int range (!).So hash collisions can bemore frequent than needed.

Memory consumptionmay varyDepending on architecture and settings.

Compact OOPs are an immediate gain.And they're fast -- we will see why later.

Page 40: sizeof(Object): how much memory objects take on JVMs and when this may matter

Fields

Page 41: sizeof(Object): how much memory objects take on JVMs and when this may matter

Unsafe can provide the "offset" of a eld relative to its base.public static class MyClass {public byte byteField = (byte) 0xfe;

}

Object o1 = new MyClass();

System.out.println(BlackMagic.objectMemoryAsString(o1));

Unsafe unsafe = UnsafeAccess.unsafe();System.out.println(

"byteField offset: " +unsafe.objectFieldOffset(MyClass.class.getDeclaredField("byteField")));

-- simpleFieldOffset(com.carrotsearch.sizeofexamples.E03_Fields)0x0000 01 00 00 00 00 00 00 00 82 3c 64 ef fe 00 00 00byteField offset: 12

. ...E03 Fields

Page 42: sizeof(Object): how much memory objects take on JVMs and when this may matter

Unsafe can provide the "offset" of a eld relative to its base.public static class MyClass {public byte byteField = (byte) 0xfe;

}

Object o1 = new MyClass();

System.out.println(BlackMagic.objectMemoryAsString(o1));

Unsafe unsafe = UnsafeAccess.unsafe();System.out.println(

"byteField offset: " +unsafe.objectFieldOffset(MyClass.class.getDeclaredField("byteField")));

-- simpleFieldOffset(com.carrotsearch.sizeofexamples.E03_Fields)0x0000 01 00 00 00 00 00 00 00 82 3c 64 ef fe 00 00 00byteField offset: 12

. ...E03 Fields

Page 43: sizeof(Object): how much memory objects take on JVMs and when this may matter

What will happen if we add elds of different types?public static class MyClass2 {public byte byteField = (byte) 0xfe;public short shortField = (short) 0xaabb;public long longField = 0x1122334455667788L;

}

-- twoFieldOffsets(com.carrotsearch.sizeofexamples.E03_Fields)0x0000 01 00 00 00 00 00 00 00 59 3a 68 ef bb aa fe 000x0010 88 77 66 55 44 33 22 11byteField offset: 14shortField offset: 12longField offset: 16

Note the 'gap' at offset 15 -- longs are aligned (in this JVM).Think of what the gap would be if we just had a long eld?

Page 44: sizeof(Object): how much memory objects take on JVMs and when this may matter

What will happen if we add elds of different types?public static class MyClass2 {public byte byteField = (byte) 0xfe;public short shortField = (short) 0xaabb;public long longField = 0x1122334455667788L;

}

-- twoFieldOffsets(com.carrotsearch.sizeofexamples.E03_Fields)0x0000 01 00 00 00 00 00 00 00 59 3a 68 ef bb aa fe 000x0010 88 77 66 55 44 33 22 11byteField offset: 14shortField offset: 12longField offset: 16

Note the 'gap' at offset 15 -- longs are aligned (in this JVM).Think of what the gap would be if we just had a long eld?

Page 45: sizeof(Object): how much memory objects take on JVMs and when this may matter

What will happen if we add elds of different types?public static class MyClass2 {public byte byteField = (byte) 0xfe;public short shortField = (short) 0xaabb;public long longField = 0x1122334455667788L;

}

-- twoFieldOffsets(com.carrotsearch.sizeofexamples.E03_Fields)0x0000 01 00 00 00 00 00 00 00 59 3a 68 ef bb aa fe 000x0010 88 77 66 55 44 33 22 11byteField offset: 14shortField offset: 12longField offset: 16

Note the 'gap' at offset 15 -- longs are aligned (in this JVM).

Think of what the gap would be if we just had a long eld?

Page 46: sizeof(Object): how much memory objects take on JVMs and when this may matter

What will happen if we add elds of different types?public static class MyClass2 {public byte byteField = (byte) 0xfe;public short shortField = (short) 0xaabb;public long longField = 0x1122334455667788L;

}

-- twoFieldOffsets(com.carrotsearch.sizeofexamples.E03_Fields)0x0000 01 00 00 00 00 00 00 00 59 3a 68 ef bb aa fe 000x0010 88 77 66 55 44 33 22 11byteField offset: 14shortField offset: 12longField offset: 16

Note the 'gap' at offset 15 -- longs are aligned (in this JVM).Think of what the gap would be if we just had a long eld?

Page 47: sizeof(Object): how much memory objects take on JVMs and when this may matter

What happens if we have inheritance? Say:public static class MyClass2 {public byte byteField = (byte) 0xfe;public short shortField = (short) 0xaabb;public long longField = 0x1122334455667788L;

}

public static class MyClass3 extends MyClass2 {public byte byteField2 = (byte) 0xfa;

}

-- inheritedFields(com.carrotsearch.sizeofexamples.E03_Fields)0x0000 01 00 00 00 00 00 00 00 3d 8f 67 ef bb aa fe 000x0010 88 77 66 55 44 33 22 11 ff 00 00 00 00 00 00 00byteField2 offset: 24byteField offset: 14shortField offset: 12longField offset: 16

But: IBM's J9 can "pack" elds in an inheritance hierarchy.

Page 48: sizeof(Object): how much memory objects take on JVMs and when this may matter

What happens if we have inheritance? Say:public static class MyClass2 {public byte byteField = (byte) 0xfe;public short shortField = (short) 0xaabb;public long longField = 0x1122334455667788L;

}

public static class MyClass3 extends MyClass2 {public byte byteField2 = (byte) 0xfa;

}

-- inheritedFields(com.carrotsearch.sizeofexamples.E03_Fields)0x0000 01 00 00 00 00 00 00 00 3d 8f 67 ef bb aa fe 000x0010 88 77 66 55 44 33 22 11 ff 00 00 00 00 00 00 00byteField2 offset: 24byteField offset: 14shortField offset: 12longField offset: 16

But: IBM's J9 can "pack" elds in an inheritance hierarchy.

Page 49: sizeof(Object): how much memory objects take on JVMs and when this may matter

What happens if we have inheritance? Say:public static class MyClass2 {public byte byteField = (byte) 0xfe;public short shortField = (short) 0xaabb;public long longField = 0x1122334455667788L;

}

public static class MyClass3 extends MyClass2 {public byte byteField2 = (byte) 0xfa;

}

-- inheritedFields(com.carrotsearch.sizeofexamples.E03_Fields)0x0000 01 00 00 00 00 00 00 00 3d 8f 67 ef bb aa fe 000x0010 88 77 66 55 44 33 22 11 ff 00 00 00 00 00 00 00byteField2 offset: 24byteField offset: 14shortField offset: 12longField offset: 16

But: IBM's J9 can "pack" elds in an inheritance hierarchy.

Page 50: sizeof(Object): how much memory objects take on JVMs and when this may matter

How about different VMs?public static class MyClass4 {public byte byteField1 = (byte) 0x01;public byte byteField2 = (byte) 0x02;public byte byteField3 = (byte) 0x03;public byte byteField4 = (byte) 0x04;public short shortField = (short) 0xa1a2;public long longField = 0xb1b2b3b4b5b6b7b8L;

}

-- vmVariance(com.carrotsearch.sizeofexamples.E03_Fields)[JVM: Oracle JRockit(R), R28.2.3-13-149708-1.6.0_31-20120327-1523-windows-x86_64]0x0000 e0 2f 47 02 00 00 00 00 b8 b7 b6 b5 b4 b3 b2 b10x0010 a2 a1 01 02 03 04 00 00

-- vmVariance(com.carrotsearch.sizeofexamples.E03_Fields)[JVM: Java HotSpot(TM) 64-Bit Server VM, 22.1-b02, Oracle Corporation, Oracle Corporation, 1.7.0_03]0x0000 01 00 00 00 00 00 00 00 44 90 67 ef a2 a1 01 020x0010 b8 b7 b6 b5 b4 b3 b2 b1 03 04 00 00 00 00 00 00

-- vmVariance(com.carrotsearch.sizeofexamples.E03_Fields)[JVM: IBM J9 VM, 2.4, IBM Corporation, IBM Corporation, 1.6.0]0x0000 b0 6a 7f 6b 0e 80 a6 43 00 00 00 00 b8 b7 b6 b50x0010 b4 b3 b2 b1 01 00 00 00 02 00 00 00 03 00 00 000x0020 04 00 00 00 a2 a1 ff ff

(note byte elds are also padded on J9!).

Page 51: sizeof(Object): how much memory objects take on JVMs and when this may matter

How about different VMs?public static class MyClass4 {public byte byteField1 = (byte) 0x01;public byte byteField2 = (byte) 0x02;public byte byteField3 = (byte) 0x03;public byte byteField4 = (byte) 0x04;public short shortField = (short) 0xa1a2;public long longField = 0xb1b2b3b4b5b6b7b8L;

}

-- vmVariance(com.carrotsearch.sizeofexamples.E03_Fields)[JVM: Oracle JRockit(R), R28.2.3-13-149708-1.6.0_31-20120327-1523-windows-x86_64]0x0000 e0 2f 47 02 00 00 00 00 b8 b7 b6 b5 b4 b3 b2 b10x0010 a2 a1 01 02 03 04 00 00

-- vmVariance(com.carrotsearch.sizeofexamples.E03_Fields)[JVM: Java HotSpot(TM) 64-Bit Server VM, 22.1-b02, Oracle Corporation, Oracle Corporation, 1.7.0_03]0x0000 01 00 00 00 00 00 00 00 44 90 67 ef a2 a1 01 020x0010 b8 b7 b6 b5 b4 b3 b2 b1 03 04 00 00 00 00 00 00

-- vmVariance(com.carrotsearch.sizeofexamples.E03_Fields)[JVM: IBM J9 VM, 2.4, IBM Corporation, IBM Corporation, 1.6.0]0x0000 b0 6a 7f 6b 0e 80 a6 43 00 00 00 00 b8 b7 b6 b50x0010 b4 b3 b2 b1 01 00 00 00 02 00 00 00 03 00 00 000x0020 04 00 00 00 a2 a1 ff ff

(note byte elds are also padded on J9!).

Page 52: sizeof(Object): how much memory objects take on JVMs and when this may matter

How about different VMs?public static class MyClass4 {public byte byteField1 = (byte) 0x01;public byte byteField2 = (byte) 0x02;public byte byteField3 = (byte) 0x03;public byte byteField4 = (byte) 0x04;public short shortField = (short) 0xa1a2;public long longField = 0xb1b2b3b4b5b6b7b8L;

}

-- vmVariance(com.carrotsearch.sizeofexamples.E03_Fields)[JVM: Oracle JRockit(R), R28.2.3-13-149708-1.6.0_31-20120327-1523-windows-x86_64]0x0000 e0 2f 47 02 00 00 00 00 b8 b7 b6 b5 b4 b3 b2 b10x0010 a2 a1 01 02 03 04 00 00

-- vmVariance(com.carrotsearch.sizeofexamples.E03_Fields)[JVM: Java HotSpot(TM) 64-Bit Server VM, 22.1-b02, Oracle Corporation, Oracle Corporation, 1.7.0_03]0x0000 01 00 00 00 00 00 00 00 44 90 67 ef a2 a1 01 020x0010 b8 b7 b6 b5 b4 b3 b2 b1 03 04 00 00 00 00 00 00

-- vmVariance(com.carrotsearch.sizeofexamples.E03_Fields)[JVM: IBM J9 VM, 2.4, IBM Corporation, IBM Corporation, 1.6.0]0x0000 b0 6a 7f 6b 0e 80 a6 43 00 00 00 00 b8 b7 b6 b50x0010 b4 b3 b2 b1 01 00 00 00 02 00 00 00 03 00 00 000x0020 04 00 00 00 a2 a1 ff ff

(note byte elds are also padded on J9!).

Page 53: sizeof(Object): how much memory objects take on JVMs and when this may matter

How about different VMs?public static class MyClass4 {public byte byteField1 = (byte) 0x01;public byte byteField2 = (byte) 0x02;public byte byteField3 = (byte) 0x03;public byte byteField4 = (byte) 0x04;public short shortField = (short) 0xa1a2;public long longField = 0xb1b2b3b4b5b6b7b8L;

}

-- vmVariance(com.carrotsearch.sizeofexamples.E03_Fields)[JVM: Oracle JRockit(R), R28.2.3-13-149708-1.6.0_31-20120327-1523-windows-x86_64]0x0000 e0 2f 47 02 00 00 00 00 b8 b7 b6 b5 b4 b3 b2 b10x0010 a2 a1 01 02 03 04 00 00

-- vmVariance(com.carrotsearch.sizeofexamples.E03_Fields)[JVM: Java HotSpot(TM) 64-Bit Server VM, 22.1-b02, Oracle Corporation, Oracle Corporation, 1.7.0_03]0x0000 01 00 00 00 00 00 00 00 44 90 67 ef a2 a1 01 020x0010 b8 b7 b6 b5 b4 b3 b2 b1 03 04 00 00 00 00 00 00

-- vmVariance(com.carrotsearch.sizeofexamples.E03_Fields)[JVM: IBM J9 VM, 2.4, IBM Corporation, IBM Corporation, 1.6.0]0x0000 b0 6a 7f 6b 0e 80 a6 43 00 00 00 00 b8 b7 b6 b50x0010 b4 b3 b2 b1 01 00 00 00 02 00 00 00 03 00 00 000x0020 04 00 00 00 a2 a1 ff ff

(note byte elds are also padded on J9!).

Page 54: sizeof(Object): how much memory objects take on JVMs and when this may matter

Conclusions so far

Field order and layout varies greatlyEach VM/hardware con g will have its own.

Memory is "lost" on paddingsVMs try to reorder and pack elds though.

Paddings are not useless crapVM designers aremachine code experts!

Page 55: sizeof(Object): how much memory objects take on JVMs and when this may matter

Object alignment

Page 56: sizeof(Object): how much memory objects take on JVMs and when this may matter

How large is an object of MyClass (byte#)?public static class MyClass {public byte byteField = (byte) 0xfe;

}

-- simpleFieldOffset(com.carrotsearch.sizeofexamples.E03_Fields)0x0000 01 00 00 00 00 00 00 00 82 3c 64 ef fe 00 00 00byteField offset: 12

Objects are placed on a "grid" of aligned addresses.

Efficient compact references: address scaling by a constant.

Page 57: sizeof(Object): how much memory objects take on JVMs and when this may matter

How large is an object of MyClass (byte#)?public static class MyClass {public byte byteField = (byte) 0xfe;

}

-- simpleFieldOffset(com.carrotsearch.sizeofexamples.E03_Fields)0x0000 01 00 00 00 00 00 00 00 82 3c 64 ef fe 00 00 00byteField offset: 12

Objects are placed on a "grid" of aligned addresses.

Efficient compact references: address scaling by a constant.

Page 58: sizeof(Object): how much memory objects take on JVMs and when this may matter

How large is an object of MyClass (byte#)?public static class MyClass {public byte byteField = (byte) 0xfe;

}

-- simpleFieldOffset(com.carrotsearch.sizeofexamples.E03_Fields)0x0000 01 00 00 00 00 00 00 00 82 3c 64 ef fe 00 00 00byteField offset: 12

Objects are placed on a "grid" of aligned addresses.

Efficient compact references: address scaling by a constant.

Page 59: sizeof(Object): how much memory objects take on JVMs and when this may matter

How large is an object of MyClass (byte#)?public static class MyClass {public byte byteField = (byte) 0xfe;

}

-- simpleFieldOffset(com.carrotsearch.sizeofexamples.E03_Fields)0x0000 01 00 00 00 00 00 00 00 82 3c 64 ef fe 00 00 00byteField offset: 12

Objects are placed on a "grid" of aligned addresses.

Efficient compact references: address scaling by a constant.

Page 60: sizeof(Object): how much memory objects take on JVMs and when this may matter

How can we determine the size of object padding in use?

On HotSpot:com.sun.management.HotSpotDiagnosticMXBean mbean =

(HotSpotDiagnosticMXBean) ManagementFactory.newPlatformMXBeanProxy(ManagementFactory.getPlatformMBeanServer(),"com.sun.management:type=HotSpotDiagnostic",HotSpotDiagnosticMXBean.class);

System.out.println("ObjectAlignment: " +mbean.getVMOption("ObjectAlignmentInBytes").getValue());

System.out.println(BlackMagic.objectMemoryAsString(new Object()));

-- simpleFieldOffset(com.carrotsearch.sizeofexamples.E04_Paddings)ObjectAlignment: 80x0000 01 00 00 00 00 00 00 00 cb 11 5c ef 00 00 00 00

. ...E04 Paddings

Page 61: sizeof(Object): how much memory objects take on JVMs and when this may matter

How can we determine the size of object padding in use?

On HotSpot:com.sun.management.HotSpotDiagnosticMXBean mbean =

(HotSpotDiagnosticMXBean) ManagementFactory.newPlatformMXBeanProxy(ManagementFactory.getPlatformMBeanServer(),"com.sun.management:type=HotSpotDiagnostic",HotSpotDiagnosticMXBean.class);

System.out.println("ObjectAlignment: " +mbean.getVMOption("ObjectAlignmentInBytes").getValue());

System.out.println(BlackMagic.objectMemoryAsString(new Object()));

-- simpleFieldOffset(com.carrotsearch.sizeofexamples.E04_Paddings)ObjectAlignment: 80x0000 01 00 00 00 00 00 00 00 cb 11 5c ef 00 00 00 00

. ...E04 Paddings

Page 62: sizeof(Object): how much memory objects take on JVMs and when this may matter

How can we determine the size of object padding in use?

On HotSpot:com.sun.management.HotSpotDiagnosticMXBean mbean =

(HotSpotDiagnosticMXBean) ManagementFactory.newPlatformMXBeanProxy(ManagementFactory.getPlatformMBeanServer(),"com.sun.management:type=HotSpotDiagnostic",HotSpotDiagnosticMXBean.class);

System.out.println("ObjectAlignment: " +mbean.getVMOption("ObjectAlignmentInBytes").getValue());

System.out.println(BlackMagic.objectMemoryAsString(new Object()));

-- simpleFieldOffset(com.carrotsearch.sizeofexamples.E04_Paddings)ObjectAlignment: 80x0000 01 00 00 00 00 00 00 00 cb 11 5c ef 00 00 00 00

. ...E04 Paddings

Page 63: sizeof(Object): how much memory objects take on JVMs and when this may matter

Wait. . . if it's an option, can we change it?!-XX:ObjectAlignmentInBytes=32

-- simpleFieldOffset(com.carrotsearch.sizeofexamples.E04_Paddings)ObjectAlignment: 320x0000 01 00 00 00 00 00 00 00 76 05 d7 fb 00 00 00 000x0010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

Not smaller than 8 though (remember - compact oops scaling!).error: ObjectAlignmentInBytes=4 must be greater or equal 8

Page 64: sizeof(Object): how much memory objects take on JVMs and when this may matter

Wait. . . if it's an option, can we change it?!-XX:ObjectAlignmentInBytes=32

-- simpleFieldOffset(com.carrotsearch.sizeofexamples.E04_Paddings)ObjectAlignment: 320x0000 01 00 00 00 00 00 00 00 76 05 d7 fb 00 00 00 000x0010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

Not smaller than 8 though (remember - compact oops scaling!).error: ObjectAlignmentInBytes=4 must be greater or equal 8

Page 65: sizeof(Object): how much memory objects take on JVMs and when this may matter

Wait. . . if it's an option, can we change it?!-XX:ObjectAlignmentInBytes=32

-- simpleFieldOffset(com.carrotsearch.sizeofexamples.E04_Paddings)ObjectAlignment: 320x0000 01 00 00 00 00 00 00 00 76 05 d7 fb 00 00 00 000x0010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

Not smaller than 8 though (remember - compact oops scaling!).error: ObjectAlignmentInBytes=4 must be greater or equal 8

Page 66: sizeof(Object): how much memory objects take on JVMs and when this may matter

Arrays and index scaling

Page 67: sizeof(Object): how much memory objects take on JVMs and when this may matter

ArraysThe same kind of analysis can be applied to arrays:• where is array's length stored?• how are individual elements stored?• are there any paddings?

This is your homework :)

Page 68: sizeof(Object): how much memory objects take on JVMs and when this may matter

ArraysThe same kind of analysis can be applied to arrays:• where is array's length stored?• how are individual elements stored?• are there any paddings?

This is your homework :)

Page 69: sizeof(Object): how much memory objects take on JVMs and when this may matter

False sharing

Page 70: sizeof(Object): how much memory objects take on JVMs and when this may matter

False sharing

Memory split into cache lines64 bytes, typically. Withmultiple cache levels.

Cache access speeds varyA lot!

Fields or even objects can share a cache line.Multithreaded access to con icting cache lines will slow down apps.

Page 71: sizeof(Object): how much memory objects take on JVMs and when this may matter

An example (code simpli ed):AtomicLongArray array = new AtomicLongArray(largeEnough);

for (int threads = 1; threads <= 8; threads++)for (int sepIndexes : new int [] {0, 0, 0, 1, .... 8, 9, 10, 11, 12, 13, 1000})runRound(threads, sepIndexes);

runRound(N, sep) {// start N threads, each reading/ writing to// array[threads_index * sep]

}

. ...E05 FalseSharing

Page 72: sizeof(Object): how much memory objects take on JVMs and when this may matter

.

.

Page 73: sizeof(Object): how much memory objects take on JVMs and when this may matter

Conclusions so far

False sharing is a real problem (?)If you have lots of concurrent operations.

No low-level control in Java (without JNI)Thread-core affinity, cache line alignments.

Array traversals may be tricky!Built-in bounds checkingmay cause false sharing (unless eliminated).

Page 74: sizeof(Object): how much memory objects take on JVMs and when this may matter

Summary

Page 75: sizeof(Object): how much memory objects take on JVMs and when this may matter

Is any of this useful?

Page 76: sizeof(Object): how much memory objects take on JVMs and when this may matter

Is any of this useful?Maybe not on a daily basis.

Page 77: sizeof(Object): how much memory objects take on JVMs and when this may matter

Is any of this useful?But try to estimate the "object overhead" of a large

HashMap<String,Byte>

Page 78: sizeof(Object): how much memory objects take on JVMs and when this may matter

HashMap<String,Byte> hm = Maps.newHashMap();hm.put("a", (byte) 1);hm.put("b", (byte) 2);hm.put("c", (byte) 3);

System.out.println(ObjectTree.dump(hm));

-- hashMapTree(com.carrotsearch.sizeofexamples.E08_HashMapTree)440 48 root => <HashMap#0>0 0 +- Set entrySet => null0 0 +- Set keySet => null

392 80 +- Entry[] table => Entry[]104 32 | +- [4] => <Entry#2>56 32 | | +- Object key => <String#3>24 24 | | | +- char[] value => char[]0 0 | | +- Entry next => null16 16 | | +- Object value => <Byte#5>104 32 | +- [5] => <Entry#6>56 32 | | +- Object key => <String#7>24 24 | | | +- char[] value => char[]0 0 | | +- Entry next => null16 16 | | +- Object value => <Byte#9>104 32 | +- [7] => <Entry#10>56 32 | +- Object key => <String#11>24 24 | | +- char[] value => char[]0 0 | +- Entry next => null16 16 | +- Object value => <Byte#13>0 0 +- Collection values => null

Page 79: sizeof(Object): how much memory objects take on JVMs and when this may matter

HashMap<String,Byte> hm = Maps.newHashMap();hm.put("a", (byte) 1);hm.put("b", (byte) 2);hm.put("c", (byte) 3);

System.out.println(ObjectTree.dump(hm));

-- hashMapTree(com.carrotsearch.sizeofexamples.E08_HashMapTree)440 48 root => <HashMap#0>0 0 +- Set entrySet => null0 0 +- Set keySet => null

392 80 +- Entry[] table => Entry[]104 32 | +- [4] => <Entry#2>56 32 | | +- Object key => <String#3>24 24 | | | +- char[] value => char[]0 0 | | +- Entry next => null16 16 | | +- Object value => <Byte#5>104 32 | +- [5] => <Entry#6>56 32 | | +- Object key => <String#7>24 24 | | | +- char[] value => char[]0 0 | | +- Entry next => null16 16 | | +- Object value => <Byte#9>104 32 | +- [7] => <Entry#10>56 32 | +- Object key => <String#11>24 24 | | +- char[] value => char[]0 0 | +- Entry next => null16 16 | +- Object value => <Byte#13>0 0 +- Collection values => null

Page 80: sizeof(Object): how much memory objects take on JVMs and when this may matter

java-sizeofhttps://github.com/dweiss/java-sizeof

Ready-to-use code, including object hexdumper.Similar code in Apache Lucene (joint work with Uwe Schindler).

Page 81: sizeof(Object): how much memory objects take on JVMs and when this may matter
Page 82: sizeof(Object): how much memory objects take on JVMs and when this may matter

Why the example needs a volatile?Holder holder = array[index];for (int i = 0; i < OPS; i++) {holder.value++;

}

Non-volatile eld:0x00007f86928087c4: mov %r11d,%ecx0x00007f86928087c7: add %r8d,%ecx0x00007f86928087ca: inc %r11d0x00007f86928087cd: inc %ecx0x00007f86928087cf: mov %ecx,0xc(%r10)

0x00007f86928087d3: cmp $0x989680,%r11d0x00007f86928087da: jl 0x00007f86928087c4

Volatile eld:0x00007fe2ba6e8208: mov 0xc(%r10),%r8d0x00007fe2ba6e820c: inc %r11d0x00007fe2ba6e820f: inc %r8d0x00007fe2ba6e8212: mov %r8d,0xc(%r10)0x00007fe2ba6e8216: lock addl $0x0,(%rsp)0x00007fe2ba6e821b: cmp $0x989680,%r11d0x00007fe2ba6e8222: jl 0x00007fe2ba6e8208