SlideShare une entreprise Scribd logo
1  sur  82
Télécharger pour lire hors ligne
sizeof(new Object())
how much memory objects take on JVMs
. . . and when this may matter




Dawid Weiss
Carrot Search s.c.
Poznań, May 2012
.



            Dawid Weiss
        .
            Likes coding
            10 years assembly only

    .       Likes research
            Former academic. PhD in IR.

            Likes open source
            Carrot2, HPPC, Lucene PMC, . . .

            Likes industry
            Carrot Search s.c.




.       .
Memory
A byte

    8 bits      7   6    5   4   3   2        1   0


    2 nibbles           hi               lo


    1 byte                   byte
A byte (concrete value)

    8 bits      1   1       1   0    0   0       1   1


    2 nibbles           E                    3


    1 byte                          E3
Memory (*)
A linear sequence of bytes, each one at a certain offset
(address), starting with 0.
hexdump
A textual dump of bytes from memory or le. May be
accompanied by (US-ASCII) character codes.
hexdump
A textual dump of bytes from memory or le. May be
accompanied 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......"..|
...
Types in Java
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 483 648 elements.
Primitives
       type      required bytes
       byte            1
       boolean         1
       char            2
       short           2
       float           4
       int             4
       double          8
       long            8
Objects
public class MyClass {
  public boolean field1;
  public int     field2;
  public Object field3;
}
Objects
public class MyClass {
  public boolean field1;
  public int     field2;
  public Object field3;
}




What's sizeof(new MyClass())?
Objects
public class MyClass {
  public boolean field1;
  public int     field2;
  public Object field3;
}




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

(But sometimes we'd like to know.)
Access to low-level Java
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.Unsafe
SUN's box of "only we can touch it" toys. Inherited by most other vendors (be-
cause of sublicensing, for compatibility?).
Hexdumping Java objects
WARN: any of the code shown further on relies on
undocumented and unspeci ed JVM internals and may not
                work or even compile.
Acquiring Unsafe instance like this:
sun.misc.Unsafe.getUnsafe();

java.lang.SecurityException: Unsafe
at sun.misc.Unsafe.getUnsafe(Unsafe.java:68)
at com.carrotsearch.sizeofexamples.UnsafeAccess.unsafe(UnsafeAccess.java:8)
...
Acquiring Unsafe instance like this:
sun.misc.Unsafe.getUnsafe();

java.lang.SecurityException: Unsafe
at 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);
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);
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?
public static class MyClass {
      public byte field;
      public MyClass(byte v) { field = v; }
    }


      @Test
      public 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();
      }




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


      @Test
      public 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 00
    01    00 00 00 00 00 00 00 60 a5 21 bd fa 00 00 00
    01    00 00 00 00 00 00 00 60 a5 21 bd f0 00 00 00
    01    00 00 00 00 00 00 00 f0 28 e1 bc 28 6d 88 eb




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


      @Test
      public 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();
      }




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


      @Test
      public 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 aa
    01    00 00 00 00 00 00 00 08 f6 21 bd 44 33 22 11
    01    00 00 00 00 00 00 00 f0 df e5 bc 01 00 00 00
    00    00 00 00 1a 00 00 00 78 1f ed bc 70 b1 21 bd




                                                                               .
                                                                               E01 Alignments .
                                                                               .
.
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 order
But it is veri able -- java.nio.ByteOrder.
Conclusions so far
Object 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 00
01   00 00 00 00 00 00 00 60 a5 21 bd fa 00 00 00
01   00 00 00 00 00 00 00 60 a5 21 bd f0 00 00 00
01   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?
Object header
openjdk/hotspot/src/share/vm/oops/oopsHierarchy.hpp
openjdk/hotspot/src/share/vm/oops/oopsHierarchy.hpp

class oopDesc {
  // ...
  volatile markOop _mark;
  union _metadata {
    wideKlassOop    _klass;
    narrowOop       _compressed_klass;
  } _metadata;
  // ...
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 obj
//    unused:21 size:35 -->|     cms_free:1   unused:7   ------------------>|   (COOPs   &&   CMS free block)
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 .
.
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 00
After identity hash: 7bf90a55
0x0000 01 55 0a f9 7b 00 00 00 d8 dc 1b bd fe 00 00 00
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 00
After identity hash: 7bf90a55
0x0000 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 00
After identity hash: 005e176f
0x0000 81 b7 0b 2f 90 5c 3d b2 fe 00 00 00 00 00 00 00
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 00
After identity hash: 7bf90a55
0x0000 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 00
After identity hash: 005e176f
0x0000 81 b7 0b 2f 90 5c 3d b2 fe 00 00 00 00 00 00 00

(2f0bb781 >> 7 = 5e176f)
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 00
After identity hash: 7bf90a55
0x0000 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 00
After identity hash: 005e176f
0x0000 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 00
0x0010 fe 00 00 00 00 00 00 00
After identity hash: 7bf90a55
0x0000 01 55 0a f9 7b 00 00 00 d0 d6 eb a3 13 7f 00 00
0x0010 fe 00 00 00 00 00 00 00
Conclusions so far

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

Memory consumption may vary
Depending on architecture and settings.

Compact OOPs are an immediate gain.
And they're fast -- we will see why later.
Fields
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")));




                                                                                      .
                                                                                      .
                                                                                      E03 Fields .
.
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 00
    byteField offset: 12




                                                                                      .
                                                                                      .
                                                                                      E03 Fields .
.
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;
}
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 00
0x0010 88 77 66 55 44 33 22 11
byteField offset: 14
shortField offset: 12
longField offset: 16
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 00
0x0010 88 77 66 55 44 33 22 11
byteField offset: 14
shortField offset: 12
longField offset: 16


Note the 'gap' at offset 15 -- longs are aligned (in this JVM).
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 00
0x0010 88 77 66 55 44 33 22 11
byteField offset: 14
shortField offset: 12
longField 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?
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;
}
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 00
0x0010 88 77 66 55 44 33 22 11 ff 00 00 00 00 00 00 00
byteField2 offset: 24
byteField offset: 14
shortField offset: 12
longField offset: 16
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 00
0x0010 88 77 66 55 44 33 22 11 ff 00 00 00 00 00 00 00
byteField2 offset: 24
byteField offset: 14
shortField offset: 12
longField offset: 16




But: IBM's J9 can "pack" elds in an inheritance hierarchy.
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;
}
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 b1
0x0010 a2 a1 01 02 03 04 00 00
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 b1
0x0010 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.
0x0000 01 00 00 00 00 00 00 00 44 90 67 ef a2 a1 01 02
0x0010 b8 b7 b6 b5 b4 b3 b2 b1 03 04 00 00 00 00 00 00
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 b1
0x0010 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.
0x0000 01 00 00 00 00 00 00 00 44 90 67 ef a2 a1 01 02
0x0010 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 b5
0x0010 b4 b3 b2 b1 01 00 00 00 02 00 00 00 03 00 00 00
0x0020 04 00 00 00 a2 a1 ff ff


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

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

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

Paddings are not useless crap
VM designers are machine code experts!
Object alignment
How large is an object of MyClass (byte#)?
public static class MyClass {
  public byte byteField = (byte) 0xfe;
}
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 00
byteField offset: 12
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 00
byteField offset: 12



Objects are placed on a "grid" of aligned addresses.
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 00
byteField offset: 12



Objects are placed on a "grid" of aligned addresses.
Efficient compact references: address scaling by a constant.
How can we determine the size of object padding in use?




                                                          .
                                                          E04 Paddings .
                                                          .
.
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()));




                                                                              .
                                                                              E04 Paddings .
                                                                              .
.
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: 8
    0x0000 01 00 00 00 00 00 00 00 cb 11 5c ef 00 00 00 00




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


-- simpleFieldOffset(com.carrotsearch.sizeofexamples.E04_Paddings)
ObjectAlignment: 32
0x0000 01 00 00 00 00 00 00 00 76 05 d7 fb 00 00 00 00
0x0010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Wait. . . if it's an option, can we change it?!
-XX:ObjectAlignmentInBytes=32


-- simpleFieldOffset(com.carrotsearch.sizeofexamples.E04_Paddings)
ObjectAlignment: 32
0x0000 01 00 00 00 00 00 00 00 76 05 d7 fb 00 00 00 00
0x0010 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
Arrays and index scaling
Arrays
The same kind of analysis can be applied to arrays:
• where is array's length stored?
• how are individual elements stored?
• are there any paddings?
Arrays
The 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 :)
False sharing
False sharing

Memory split into cache lines
64 bytes, typically. With multiple cache levels.

Cache access speeds vary
A lot!

Fields or even objects can share a cache line.
Multithreaded access to con icting cache lines will slow down apps.
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 .
                                                                           .
.
.




.
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 checking may cause false sharing (unless eliminated).
Summary
Is any of this useful?
Is any of this useful?
    Maybe not on a daily basis.
Is any of this useful?
But try to estimate the "object overhead" of a large
               HashMap<String,Byte>
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));
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 => null
      0     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 => null
     16    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 => null
     16    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 => null
     16    16 |    +- Object value => <Byte#13>
      0     0 +- Collection values => null
java-sizeof
            https://github.com/dweiss/java-sizeof
       Ready-to-use code, including object hexdumper.
Similar code in Apache Lucene (joint work with Uwe Schindler).
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,%ecx
 0x00007f86928087c7:   add   %r8d,%ecx
 0x00007f86928087ca:   inc   %r11d
 0x00007f86928087cd:   inc   %ecx
 0x00007f86928087cf:   mov   %ecx,0xc(%r10)

 0x00007f86928087d3: cmp $0x989680,%r11d
 0x00007f86928087da: jl 0x00007f86928087c4



Volatile eld:
 0x00007fe2ba6e8208:   mov 0xc(%r10),%r8d
 0x00007fe2ba6e820c:   inc %r11d
 0x00007fe2ba6e820f:   inc %r8d
 0x00007fe2ba6e8212:   mov %r8d,0xc(%r10)
 0x00007fe2ba6e8216:   lock addl $0x0,(%rsp)
 0x00007fe2ba6e821b:   cmp $0x989680,%r11d
 0x00007fe2ba6e8222:   jl 0x00007fe2ba6e8208

Contenu connexe

Tendances

Chapter 8 c solution
Chapter 8 c solutionChapter 8 c solution
Chapter 8 c solutionAzhar Javed
 
ES6 presentation
ES6 presentationES6 presentation
ES6 presentationritika1
 
An introduction to Rust: the modern programming language to develop safe and ...
An introduction to Rust: the modern programming language to develop safe and ...An introduction to Rust: the modern programming language to develop safe and ...
An introduction to Rust: the modern programming language to develop safe and ...Claudio Capobianco
 
5 collection framework
5 collection framework5 collection framework
5 collection frameworkMinal Maniar
 
Parboiled explained
Parboiled explainedParboiled explained
Parboiled explainedPaul Popoff
 
What are variables and keywords in c++
What are variables and keywords in c++What are variables and keywords in c++
What are variables and keywords in c++Abdul Hafeez
 
Exception handling in java
Exception handling in javaException handling in java
Exception handling in javaARAFAT ISLAM
 
Boost your productivity with Scala tooling!
Boost your productivity  with Scala tooling!Boost your productivity  with Scala tooling!
Boost your productivity with Scala tooling!MeriamLachkar1
 
If You Think You Can Stay Away from Functional Programming, You Are Wrong
If You Think You Can Stay Away from Functional Programming, You Are WrongIf You Think You Can Stay Away from Functional Programming, You Are Wrong
If You Think You Can Stay Away from Functional Programming, You Are WrongMario Fusco
 
V8 javascript engine for フロントエンドデベロッパー
V8 javascript engine for フロントエンドデベロッパーV8 javascript engine for フロントエンドデベロッパー
V8 javascript engine for フロントエンドデベロッパーTaketoshi 青野健利
 
Reliable Windows Heap Exploits
Reliable Windows Heap ExploitsReliable Windows Heap Exploits
Reliable Windows Heap Exploitsamiable_indian
 
Sigreturn Oriented Programming
Sigreturn Oriented ProgrammingSigreturn Oriented Programming
Sigreturn Oriented ProgrammingAngel Boy
 
Introduction to Rust language programming
Introduction to Rust language programmingIntroduction to Rust language programming
Introduction to Rust language programmingRodolfo Finochietti
 

Tendances (20)

Chapter 8 c solution
Chapter 8 c solutionChapter 8 c solution
Chapter 8 c solution
 
Functions in c
Functions in cFunctions in c
Functions in c
 
ES6 presentation
ES6 presentationES6 presentation
ES6 presentation
 
Indexing
IndexingIndexing
Indexing
 
An introduction to Rust: the modern programming language to develop safe and ...
An introduction to Rust: the modern programming language to develop safe and ...An introduction to Rust: the modern programming language to develop safe and ...
An introduction to Rust: the modern programming language to develop safe and ...
 
Java Generics
Java GenericsJava Generics
Java Generics
 
5 collection framework
5 collection framework5 collection framework
5 collection framework
 
Parboiled explained
Parboiled explainedParboiled explained
Parboiled explained
 
What are variables and keywords in c++
What are variables and keywords in c++What are variables and keywords in c++
What are variables and keywords in c++
 
Exception handling in java
Exception handling in javaException handling in java
Exception handling in java
 
Variadic functions
Variadic functionsVariadic functions
Variadic functions
 
Java Generics - by Example
Java Generics - by ExampleJava Generics - by Example
Java Generics - by Example
 
Boost your productivity with Scala tooling!
Boost your productivity  with Scala tooling!Boost your productivity  with Scala tooling!
Boost your productivity with Scala tooling!
 
If You Think You Can Stay Away from Functional Programming, You Are Wrong
If You Think You Can Stay Away from Functional Programming, You Are WrongIf You Think You Can Stay Away from Functional Programming, You Are Wrong
If You Think You Can Stay Away from Functional Programming, You Are Wrong
 
V8 javascript engine for フロントエンドデベロッパー
V8 javascript engine for フロントエンドデベロッパーV8 javascript engine for フロントエンドデベロッパー
V8 javascript engine for フロントエンドデベロッパー
 
Sequelize
SequelizeSequelize
Sequelize
 
Reliable Windows Heap Exploits
Reliable Windows Heap ExploitsReliable Windows Heap Exploits
Reliable Windows Heap Exploits
 
Sigreturn Oriented Programming
Sigreturn Oriented ProgrammingSigreturn Oriented Programming
Sigreturn Oriented Programming
 
Introduction to Rust
Introduction to RustIntroduction to Rust
Introduction to Rust
 
Introduction to Rust language programming
Introduction to Rust language programmingIntroduction to Rust language programming
Introduction to Rust language programming
 

En vedette

Jvm internal
Jvm internalJvm internal
Jvm internalGo Tanaka
 
JavaOne 2013: Memory Efficient Java
JavaOne 2013: Memory Efficient JavaJavaOne 2013: Memory Efficient Java
JavaOne 2013: Memory Efficient JavaChris Bailey
 
Referring physicians presentation short
Referring physicians presentation shortReferring physicians presentation short
Referring physicians presentation shortAnthony DeSalvo
 
Java memory presentation
Java memory presentationJava memory presentation
Java memory presentationYury Bubnov
 
MQTT, Eclipse Paho and Java - Messaging for the Internet of Things
MQTT, Eclipse Paho and Java - Messaging for the Internet of ThingsMQTT, Eclipse Paho and Java - Messaging for the Internet of Things
MQTT, Eclipse Paho and Java - Messaging for the Internet of ThingsAndy Piper
 
Java Garbage Collection, Monitoring, and Tuning
Java Garbage Collection, Monitoring, and TuningJava Garbage Collection, Monitoring, and Tuning
Java Garbage Collection, Monitoring, and TuningCarol McDonald
 
Powering your next IoT application with MQTT - JavaOne 2014 tutorial
Powering your next IoT application with MQTT - JavaOne 2014 tutorialPowering your next IoT application with MQTT - JavaOne 2014 tutorial
Powering your next IoT application with MQTT - JavaOne 2014 tutorialBenjamin Cabé
 

En vedette (10)

Jvm internal
Jvm internalJvm internal
Jvm internal
 
JavaOne 2013: Memory Efficient Java
JavaOne 2013: Memory Efficient JavaJavaOne 2013: Memory Efficient Java
JavaOne 2013: Memory Efficient Java
 
Referring physicians presentation short
Referring physicians presentation shortReferring physicians presentation short
Referring physicians presentation short
 
Java memory presentation
Java memory presentationJava memory presentation
Java memory presentation
 
Java memory model
Java memory modelJava memory model
Java memory model
 
The Java memory model made easy
The Java memory model made easyThe Java memory model made easy
The Java memory model made easy
 
MQTT, Eclipse Paho and Java - Messaging for the Internet of Things
MQTT, Eclipse Paho and Java - Messaging for the Internet of ThingsMQTT, Eclipse Paho and Java - Messaging for the Internet of Things
MQTT, Eclipse Paho and Java - Messaging for the Internet of Things
 
Metaspace
MetaspaceMetaspace
Metaspace
 
Java Garbage Collection, Monitoring, and Tuning
Java Garbage Collection, Monitoring, and TuningJava Garbage Collection, Monitoring, and Tuning
Java Garbage Collection, Monitoring, and Tuning
 
Powering your next IoT application with MQTT - JavaOne 2014 tutorial
Powering your next IoT application with MQTT - JavaOne 2014 tutorialPowering your next IoT application with MQTT - JavaOne 2014 tutorial
Powering your next IoT application with MQTT - JavaOne 2014 tutorial
 

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

Java Performance Puzzlers
Java Performance PuzzlersJava Performance Puzzlers
Java Performance PuzzlersDoug Hawkins
 
JavaOne 2012 - JVM JIT for Dummies
JavaOne 2012 - JVM JIT for DummiesJavaOne 2012 - JVM JIT for Dummies
JavaOne 2012 - JVM JIT for DummiesCharles Nutter
 
Internet of Things Magic Show
Internet of Things Magic ShowInternet of Things Magic Show
Internet of Things Magic ShowStephen Chin
 
Optimizing array-based data structures to the limit
Optimizing array-based data structures to the limitOptimizing array-based data structures to the limit
Optimizing array-based data structures to the limitRoman Leventov
 
Learning Java 1 – Introduction
Learning Java 1 – IntroductionLearning Java 1 – Introduction
Learning Java 1 – Introductioncaswenson
 
Java Simple Programs
Java Simple ProgramsJava Simple Programs
Java Simple ProgramsUpender Upr
 
A topology of memory leaks on the JVM
A topology of memory leaks on the JVMA topology of memory leaks on the JVM
A topology of memory leaks on the JVMRafael Winterhalter
 
Intro to Java for C++ Developers
Intro to Java for C++ DevelopersIntro to Java for C++ Developers
Intro to Java for C++ DevelopersZachary Blair
 
Oct13' ----
Oct13' ----Oct13' ----
Oct13' ----Tak Lee
 
Online test program generator for RISC-V processors
Online test program generator for RISC-V processorsOnline test program generator for RISC-V processors
Online test program generator for RISC-V processorsRISC-V International
 
Materials for teachers and students java-en
Materials for teachers and students java-enMaterials for teachers and students java-en
Materials for teachers and students java-enGeorgeta Manafu
 
PVS-Studio 5.00, a solution for developers of modern resource-intensive appl...
PVS-Studio 5.00, a solution for developers of modern resource-intensive appl...PVS-Studio 5.00, a solution for developers of modern resource-intensive appl...
PVS-Studio 5.00, a solution for developers of modern resource-intensive appl...Andrey Karpov
 
"Java Concurrency Stress tests Tool" at IT Tage 2017 by Vadym Kazulkin/Rodion...
"Java Concurrency Stress tests Tool" at IT Tage 2017 by Vadym Kazulkin/Rodion..."Java Concurrency Stress tests Tool" at IT Tage 2017 by Vadym Kazulkin/Rodion...
"Java Concurrency Stress tests Tool" at IT Tage 2017 by Vadym Kazulkin/Rodion...Vadym Kazulkin
 
Os Vanrossum
Os VanrossumOs Vanrossum
Os Vanrossumoscon2007
 
The code you written is little bit confusing and lengthy. Here is th.pdf
The code you written is little bit confusing and lengthy. Here is th.pdfThe code you written is little bit confusing and lengthy. Here is th.pdf
The code you written is little bit confusing and lengthy. Here is th.pdfmohammadirfan136964
 
Don't dump thread dumps
Don't dump thread dumpsDon't dump thread dumps
Don't dump thread dumpsTier1app
 

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

Java Performance Puzzlers
Java Performance PuzzlersJava Performance Puzzlers
Java Performance Puzzlers
 
JavaOne 2012 - JVM JIT for Dummies
JavaOne 2012 - JVM JIT for DummiesJavaOne 2012 - JVM JIT for Dummies
JavaOne 2012 - JVM JIT for Dummies
 
Internet of Things Magic Show
Internet of Things Magic ShowInternet of Things Magic Show
Internet of Things Magic Show
 
Optimizing array-based data structures to the limit
Optimizing array-based data structures to the limitOptimizing array-based data structures to the limit
Optimizing array-based data structures to the limit
 
Learning Java 1 – Introduction
Learning Java 1 – IntroductionLearning Java 1 – Introduction
Learning Java 1 – Introduction
 
Java Simple Programs
Java Simple ProgramsJava Simple Programs
Java Simple Programs
 
Utility.ppt
Utility.pptUtility.ppt
Utility.ppt
 
A topology of memory leaks on the JVM
A topology of memory leaks on the JVMA topology of memory leaks on the JVM
A topology of memory leaks on the JVM
 
Java unit i
Java unit iJava unit i
Java unit i
 
Intro to Java for C++ Developers
Intro to Java for C++ DevelopersIntro to Java for C++ Developers
Intro to Java for C++ Developers
 
Oct13' ----
Oct13' ----Oct13' ----
Oct13' ----
 
Online test program generator for RISC-V processors
Online test program generator for RISC-V processorsOnline test program generator for RISC-V processors
Online test program generator for RISC-V processors
 
Materials for teachers and students java-en
Materials for teachers and students java-enMaterials for teachers and students java-en
Materials for teachers and students java-en
 
PVS-Studio 5.00, a solution for developers of modern resource-intensive appl...
PVS-Studio 5.00, a solution for developers of modern resource-intensive appl...PVS-Studio 5.00, a solution for developers of modern resource-intensive appl...
PVS-Studio 5.00, a solution for developers of modern resource-intensive appl...
 
"Java Concurrency Stress tests Tool" at IT Tage 2017 by Vadym Kazulkin/Rodion...
"Java Concurrency Stress tests Tool" at IT Tage 2017 by Vadym Kazulkin/Rodion..."Java Concurrency Stress tests Tool" at IT Tage 2017 by Vadym Kazulkin/Rodion...
"Java Concurrency Stress tests Tool" at IT Tage 2017 by Vadym Kazulkin/Rodion...
 
Nantes Jug - Java 7
Nantes Jug - Java 7Nantes Jug - Java 7
Nantes Jug - Java 7
 
Os Vanrossum
Os VanrossumOs Vanrossum
Os Vanrossum
 
The code you written is little bit confusing and lengthy. Here is th.pdf
The code you written is little bit confusing and lengthy. Here is th.pdfThe code you written is little bit confusing and lengthy. Here is th.pdf
The code you written is little bit confusing and lengthy. Here is th.pdf
 
Don't dump thread dumps
Don't dump thread dumpsDon't dump thread dumps
Don't dump thread dumps
 
What Lies Beneath
What Lies BeneathWhat Lies Beneath
What Lies Beneath
 

Dernier

[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdfSandro Moreira
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Jeffrey Haguewood
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...apidays
 
AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024The Digital Insurer
 
CNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In PakistanCNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In Pakistandanishmna97
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Victor Rentea
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProduct Anonymous
 
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...Zilliz
 
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...Angeliki Cooney
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century educationjfdjdjcjdnsjd
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfsudhanshuwaghmare1
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...Martijn de Jong
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDropbox
 
Spring Boot vs Quarkus the ultimate battle - DevoxxUK
Spring Boot vs Quarkus the ultimate battle - DevoxxUKSpring Boot vs Quarkus the ultimate battle - DevoxxUK
Spring Boot vs Quarkus the ultimate battle - DevoxxUKJago de Vreede
 
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfRising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfOrbitshub
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyKhushali Kathiriya
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FMESafe Software
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAndrey Devyatkin
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...DianaGray10
 

Dernier (20)

[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
 
AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024
 
CNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In PakistanCNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In Pakistan
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
 
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor Presentation
 
Spring Boot vs Quarkus the ultimate battle - DevoxxUK
Spring Boot vs Quarkus the ultimate battle - DevoxxUKSpring Boot vs Quarkus the ultimate battle - DevoxxUK
Spring Boot vs Quarkus the ultimate battle - DevoxxUK
 
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfRising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : Uncertainty
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 

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

  • 1. sizeof(new Object()) how much memory objects take on JVMs . . . and when this may matter Dawid Weiss Carrot Search s.c. Poznań, May 2012
  • 2. . Dawid Weiss . Likes coding 10 years assembly only . Likes research Former academic. PhD in IR. Likes open source Carrot2, HPPC, Lucene PMC, . . . Likes industry Carrot Search s.c. . .
  • 4. A byte 8 bits 7 6 5 4 3 2 1 0 2 nibbles hi lo 1 byte byte
  • 5. A byte (concrete value) 8 bits 1 1 1 0 0 0 1 1 2 nibbles E 3 1 byte E3
  • 6. Memory (*) A linear sequence of bytes, each one at a certain offset (address), starting with 0.
  • 7. hexdump A textual dump of bytes from memory or le. May be accompanied by (US-ASCII) character codes.
  • 8. hexdump A textual dump of bytes from memory or le. May be accompanied 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......"..| ...
  • 10. 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 483 648 elements.
  • 11. Primitives type required bytes byte 1 boolean 1 char 2 short 2 float 4 int 4 double 8 long 8
  • 12. Objects public class MyClass { public boolean field1; public int field2; public Object field3; }
  • 13. Objects public class MyClass { public boolean field1; public int field2; public Object field3; } What's sizeof(new MyClass())?
  • 14. Objects public class MyClass { public boolean field1; public int field2; public Object field3; } What's sizeof(new MyClass())? This is considered VM implementation and hardware detail! (But sometimes we'd like to know.)
  • 16. 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.Unsafe SUN's box of "only we can touch it" toys. Inherited by most other vendors (be- cause of sublicensing, for compatibility?).
  • 18. WARN: any of the code shown further on relies on undocumented and unspeci ed JVM internals and may not work or even compile.
  • 19. Acquiring Unsafe instance like this: sun.misc.Unsafe.getUnsafe(); java.lang.SecurityException: Unsafe at sun.misc.Unsafe.getUnsafe(Unsafe.java:68) at com.carrotsearch.sizeofexamples.UnsafeAccess.unsafe(UnsafeAccess.java:8) ...
  • 20. Acquiring Unsafe instance like this: sun.misc.Unsafe.getUnsafe(); java.lang.SecurityException: Unsafe at 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);
  • 21. 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);
  • 22. 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?
  • 23. public static class MyClass { public byte field; public MyClass(byte v) { field = v; } } @Test public 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(); } . E01 Alignments . . .
  • 24. public static class MyClass { public byte field; public MyClass(byte v) { field = v; } } @Test public 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 00 01 00 00 00 00 00 00 00 60 a5 21 bd fa 00 00 00 01 00 00 00 00 00 00 00 60 a5 21 bd f0 00 00 00 01 00 00 00 00 00 00 00 f0 28 e1 bc 28 6d 88 eb . E01 Alignments . . .
  • 25. public static class MyClassInt { public int field; public MyClassInt(int v) { field = v; } } @Test public 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(); } . E01 Alignments . . .
  • 26. public static class MyClassInt { public int field; public MyClassInt(int v) { field = v; } } @Test public 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 aa 01 00 00 00 00 00 00 00 08 f6 21 bd 44 33 22 11 01 00 00 00 00 00 00 00 f0 df e5 bc 01 00 00 00 00 00 00 00 1a 00 00 00 78 1f ed bc 70 b1 21 bd . E01 Alignments . . .
  • 27. 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 order But it is veri able -- java.nio.ByteOrder.
  • 28. Conclusions so far Object 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 00 01 00 00 00 00 00 00 00 60 a5 21 bd fa 00 00 00 01 00 00 00 00 00 00 00 60 a5 21 bd f0 00 00 00 01 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?
  • 31. openjdk/hotspot/src/share/vm/oops/oopsHierarchy.hpp class oopDesc { // ... volatile markOop _mark; union _metadata { wideKlassOop _klass; narrowOop _compressed_klass; } _metadata; // ...
  • 32. 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 obj // unused:21 size:35 -->| cms_free:1 unused:7 ------------------>| (COOPs && CMS free block)
  • 33. 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 . .
  • 34.
  • 35. 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 00 After identity hash: 7bf90a55 0x0000 01 55 0a f9 7b 00 00 00 d8 dc 1b bd fe 00 00 00
  • 36. 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 00 After identity hash: 7bf90a55 0x0000 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 00 After identity hash: 005e176f 0x0000 81 b7 0b 2f 90 5c 3d b2 fe 00 00 00 00 00 00 00
  • 37. 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 00 After identity hash: 7bf90a55 0x0000 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 00 After identity hash: 005e176f 0x0000 81 b7 0b 2f 90 5c 3d b2 fe 00 00 00 00 00 00 00 (2f0bb781 >> 7 = 5e176f)
  • 38. 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 00 After identity hash: 7bf90a55 0x0000 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 00 After identity hash: 005e176f 0x0000 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 00 0x0010 fe 00 00 00 00 00 00 00 After identity hash: 7bf90a55 0x0000 01 55 0a f9 7b 00 00 00 d0 d6 eb a3 13 7f 00 00 0x0010 fe 00 00 00 00 00 00 00
  • 39. Conclusions so far System hashCode is not a full int range (!). So hash collisions can be more frequent than needed. Memory consumption may vary Depending on architecture and settings. Compact OOPs are an immediate gain. And they're fast -- we will see why later.
  • 41. 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"))); . . E03 Fields . .
  • 42. 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 00 byteField offset: 12 . . E03 Fields . .
  • 43. 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; }
  • 44. 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 00 0x0010 88 77 66 55 44 33 22 11 byteField offset: 14 shortField offset: 12 longField offset: 16
  • 45. 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 00 0x0010 88 77 66 55 44 33 22 11 byteField offset: 14 shortField offset: 12 longField offset: 16 Note the 'gap' at offset 15 -- longs are aligned (in this JVM).
  • 46. 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 00 0x0010 88 77 66 55 44 33 22 11 byteField offset: 14 shortField offset: 12 longField 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?
  • 47. 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; }
  • 48. 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 00 0x0010 88 77 66 55 44 33 22 11 ff 00 00 00 00 00 00 00 byteField2 offset: 24 byteField offset: 14 shortField offset: 12 longField offset: 16
  • 49. 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 00 0x0010 88 77 66 55 44 33 22 11 ff 00 00 00 00 00 00 00 byteField2 offset: 24 byteField offset: 14 shortField offset: 12 longField offset: 16 But: IBM's J9 can "pack" elds in an inheritance hierarchy.
  • 50. 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; }
  • 51. 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 b1 0x0010 a2 a1 01 02 03 04 00 00
  • 52. 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 b1 0x0010 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. 0x0000 01 00 00 00 00 00 00 00 44 90 67 ef a2 a1 01 02 0x0010 b8 b7 b6 b5 b4 b3 b2 b1 03 04 00 00 00 00 00 00
  • 53. 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 b1 0x0010 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. 0x0000 01 00 00 00 00 00 00 00 44 90 67 ef a2 a1 01 02 0x0010 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 b5 0x0010 b4 b3 b2 b1 01 00 00 00 02 00 00 00 03 00 00 00 0x0020 04 00 00 00 a2 a1 ff ff (note byte elds are also padded on J9!).
  • 54. Conclusions so far Field order and layout varies greatly Each VM/hardware con g will have its own. Memory is "lost" on paddings VMs try to reorder and pack elds though. Paddings are not useless crap VM designers are machine code experts!
  • 56. How large is an object of MyClass (byte#)? public static class MyClass { public byte byteField = (byte) 0xfe; }
  • 57. 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 00 byteField offset: 12
  • 58. 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 00 byteField offset: 12 Objects are placed on a "grid" of aligned addresses.
  • 59. 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 00 byteField offset: 12 Objects are placed on a "grid" of aligned addresses. Efficient compact references: address scaling by a constant.
  • 60. How can we determine the size of object padding in use? . E04 Paddings . . .
  • 61. 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())); . E04 Paddings . . .
  • 62. 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: 8 0x0000 01 00 00 00 00 00 00 00 cb 11 5c ef 00 00 00 00 . E04 Paddings . . .
  • 63. Wait. . . if it's an option, can we change it?! -XX:ObjectAlignmentInBytes=32
  • 64. Wait. . . if it's an option, can we change it?! -XX:ObjectAlignmentInBytes=32 -- simpleFieldOffset(com.carrotsearch.sizeofexamples.E04_Paddings) ObjectAlignment: 32 0x0000 01 00 00 00 00 00 00 00 76 05 d7 fb 00 00 00 00 0x0010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  • 65. Wait. . . if it's an option, can we change it?! -XX:ObjectAlignmentInBytes=32 -- simpleFieldOffset(com.carrotsearch.sizeofexamples.E04_Paddings) ObjectAlignment: 32 0x0000 01 00 00 00 00 00 00 00 76 05 d7 fb 00 00 00 00 0x0010 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
  • 66. Arrays and index scaling
  • 67. Arrays The same kind of analysis can be applied to arrays: • where is array's length stored? • how are individual elements stored? • are there any paddings?
  • 68. Arrays The 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 :)
  • 70. False sharing Memory split into cache lines 64 bytes, typically. With multiple cache levels. Cache access speeds vary A lot! Fields or even objects can share a cache line. Multithreaded access to con icting cache lines will slow down apps.
  • 71. 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 . . .
  • 72. . .
  • 73. 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 checking may cause false sharing (unless eliminated).
  • 75. Is any of this useful?
  • 76. Is any of this useful? Maybe not on a daily basis.
  • 77. Is any of this useful? But try to estimate the "object overhead" of a large HashMap<String,Byte>
  • 78. 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));
  • 79. 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 => null 0 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 => null 16 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 => null 16 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 => null 16 16 | +- Object value => <Byte#13> 0 0 +- Collection values => null
  • 80. java-sizeof https://github.com/dweiss/java-sizeof Ready-to-use code, including object hexdumper. Similar code in Apache Lucene (joint work with Uwe Schindler).
  • 81.
  • 82. 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,%ecx 0x00007f86928087c7: add %r8d,%ecx 0x00007f86928087ca: inc %r11d 0x00007f86928087cd: inc %ecx 0x00007f86928087cf: mov %ecx,0xc(%r10) 0x00007f86928087d3: cmp $0x989680,%r11d 0x00007f86928087da: jl 0x00007f86928087c4 Volatile eld: 0x00007fe2ba6e8208: mov 0xc(%r10),%r8d 0x00007fe2ba6e820c: inc %r11d 0x00007fe2ba6e820f: inc %r8d 0x00007fe2ba6e8212: mov %r8d,0xc(%r10) 0x00007fe2ba6e8216: lock addl $0x0,(%rsp) 0x00007fe2ba6e821b: cmp $0x989680,%r11d 0x00007fe2ba6e8222: jl 0x00007fe2ba6e8208