Code Tools: jol

JOL (Java Object Layout) is the tiny toolbox to analyze object layout schemes in JVMs. These tools are using Unsafe, JVMTI, and Serviceability Agent (SA) heavily to decoder the actual object layout, footprint, and references. This makes JOL much more accurate than other tools relying on heap dumps, specification assumptions, etc.

Building JOL from source

Check out the JOL source with Mercurial: $ hg clone http://hg.openjdk.java.net/code-tools/jol/ jol Build JOL with Maven: $ cd jol/ $ mvn clean install You only need to do this step once, and Maven will deploy JOL into your local repo. If you have the Maven repository manager installed, it might be a good idea to deploy the artifact there. If not, you can just go with the local build.

You may skip this step and use the published binaries instead, see the usage below. It is generally preferred to use the latest source version, that hopefully has the most issues fixed. Follow these steps to compile JOL from the source.

There are two major ways to use this project.

Use as Library Dependency

<dependency> <groupId>org.openjdk.jol</groupId> <artifactId>jol-core</artifactId> <version>put-the-version-here</version> </dependency>

OpenJDK Community semi-regularly pushes the releases to Maven Central . Therefore, you can use it right away by setting up the Maven dependency:

It is a good idea to review JOL Samples and CLI tools source before using the tool at its full capacity as the library.

Use as Command Line Tool

Build produces the self-contained executable JAR in jol-cli/target/jol-cli.jar . Published Maven artifacts also include the executable JAR that one can download and start using right away. To do that, look for the latest version of jol-cli-$version-full.jar here.

Run it with help argument to get the list of operations it has. The brief list of operations we have goes below:

Get the object internals, that is, the field layout within the object, header information, field values, the data on alignment losses. $ java -jar jol-cli/target/jol-cli.jar internals java.util.HashMap Running 64-bit HotSpot VM. Using compressed oop with 3-bit shift. Using compressed klass with 3-bit shift. Objects are 8 bytes aligned. Field sizes by type: 4, 1, 1, 2, 2, 4, 4, 8, 8 [bytes] Array element sizes: 4, 1, 1, 2, 2, 4, 4, 8, 8 [bytes] java.util.HashMap object internals: OFFSET SIZE TYPE DESCRIPTION VALUE 0 4 (object header) 05 00 00 00 (0000 0101 0000 0000 0000 0000 0000 0000) 4 4 (object header) 00 00 00 00 (0000 0000 0000 0000 0000 0000 0000 0000) 8 4 (object header) 8c 3b 00 f8 (1000 1100 0011 1011 0000 0000 1111 1000) 12 4 Set AbstractMap.keySet null 16 4 Collection AbstractMap.values null 20 4 int HashMap.size 0 24 4 int HashMap.modCount 0 28 4 int HashMap.threshold 0 32 4 float HashMap.loadFactor 0.75 36 4 Node[] HashMap.table null 40 4 Set HashMap.entrySet null 44 4 (loss due to the next object alignment) Instance size: 48 bytes (reported by Instrumentation API) Space losses: 0 bytes internal + 4 bytes external = 4 bytes total

Get the object externals, that is, the objects reachable from the instance, their addresses, paths through the reachability graphs, etc (is is more convenient with API though): $ java -jar jol-cli/target/jol-cli.jar externals java.util.PriorityQueue Running 64-bit HotSpot VM. Using compressed oop with 3-bit shift. Using compressed klass with 3-bit shift. Objects are 8 bytes aligned. Field sizes by type: 4, 1, 1, 2, 2, 4, 4, 8, 8 [bytes] Array element sizes: 4, 1, 1, 2, 2, 4, 4, 8, 8 [bytes] java.util.PriorityQueue object externals: ADDRESS SIZE TYPE PATH VALUE 719231ad0 32 java.util.PriorityQueue (object) 719231af0 64 [Ljava.lang.Object; .queue [null, null, null, null, null, null, null, null, null, null, null]

Get the object footprint estimate, same as the object externals, but tabulated: $ java -jar jol-cli/target/jol-cli.jar footprint java.util.Hashtable Running 64-bit HotSpot VM. Using compressed oop with 3-bit shift. Using compressed klass with 3-bit shift. Objects are 8 bytes aligned. Field sizes by type: 4, 1, 1, 2, 2, 4, 4, 8, 8 [bytes] Array element sizes: 4, 1, 1, 2, 2, 4, 4, 8, 8 [bytes] java.util.Hashtable instance footprint: COUNT AVG SUM DESCRIPTION 1 64 64 [Ljava.util.Hashtable$Entry; 1 48 48 java.util.Hashtable 2 112 (total)

Get the estimated object layout in different VM modes (EXPERIMENTAL): $ java -jar jol-cli/target/jol-cli.jar estimates java.math.BigInteger java.math.BigInteger object internals: OFFSET SIZE TYPE DESCRIPTION VALUE 0 8 (object header) N/A 8 4 int BigInteger.signum N/A 12 4 int[] BigInteger.mag N/A 16 4 int BigInteger.bitCount N/A 20 4 int BigInteger.bitLength N/A 24 4 int BigInteger.lowestSetBit N/A 28 4 int BigInteger.firstNonzeroIntNum N/A Instance size: 32 bytes (estimated, the sample instance is not available) Space losses: 0 bytes internal + 0 bytes external = 0 bytes total ***** 64-bit VM: ********************************************************** java.math.BigInteger object internals: OFFSET SIZE TYPE DESCRIPTION VALUE 0 16 (object header) N/A 16 8 int[] BigInteger.mag N/A 24 4 int BigInteger.signum N/A 28 4 int BigInteger.bitCount N/A 32 4 int BigInteger.bitLength N/A 36 4 int BigInteger.lowestSetBit N/A 40 4 int BigInteger.firstNonzeroIntNum N/A 44 4 (loss due to the next object alignment) Instance size: 48 bytes (estimated, the sample instance is not available) Space losses: 0 bytes internal + 4 bytes external = 4 bytes total ***** 64-bit VM, compressed references enabled: *************************** java.math.BigInteger object internals: OFFSET SIZE TYPE DESCRIPTION VALUE 0 12 (object header) N/A 12 4 int BigInteger.signum N/A 16 4 int[] BigInteger.mag N/A 20 4 int BigInteger.bitCount N/A 24 4 int BigInteger.bitLength N/A 28 4 int BigInteger.lowestSetBit N/A 32 4 int BigInteger.firstNonzeroIntNum N/A 36 4 (loss due to the next object alignment) Instance size: 40 bytes (estimated, the sample instance is not available) Space losses: 0 bytes internal + 4 bytes external = 4 bytes total ***** 64-bit VM, compressed references enabled, 16-byte align: ************ java.math.BigInteger object internals: OFFSET SIZE TYPE DESCRIPTION VALUE 0 12 (object header) N/A 12 4 int BigInteger.signum N/A 16 4 int[] BigInteger.mag N/A 20 4 int BigInteger.bitCount N/A 24 4 int BigInteger.bitLength N/A 28 4 int BigInteger.lowestSetBit N/A 32 4 int BigInteger.firstNonzeroIntNum N/A 36 12 (loss due to the next object alignment) Instance size: 48 bytes (estimated, the sample instance is not available) Space losses: 0 bytes internal + 12 bytes external = 12 bytes total

Consume the heap dump and figure the perceived footprint in different VM modes (EXPERIMENTAL): $ java -jar jol-cli/target/jol-cli.jar heapdump heapdump.hprof Heap Dump: heapdump.hprof Estimated heap consumed, bytes: 173,564,985: Raw data (X32 model) 179,480,339: VM Layout Simulation (X32 model) -0.000% 179,480,067: VM Layout Simulation (X32 model, hierarchy gaps) -0.000% 179,480,043: VM Layout Simulation (X32 model, super gaps) -2.692% 174,649,167: VM Layout Simulation (X32 model, autoalign) -2.693% 174,647,815: VM Layout Simulation (X32 model, hierarchy gaps, autoalign) -2.693% 174,647,803: VM Layout Simulation (X32 model, super gaps, autoalign) 232,120,233: Raw data (X64 model) 237,629,451: VM Layout Simulation (X64 model) -0.000% 237,629,155: VM Layout Simulation (X64 model, hierarchy gaps) -0.001% 237,626,779: VM Layout Simulation (X64 model, super gaps) -0.059% 237,488,735: VM Layout Simulation (X64 model, autoalign) -0.059% 237,488,439: VM Layout Simulation (X64 model, hierarchy gaps, autoalign) -0.060% 237,486,063: VM Layout Simulation (X64 model, super gaps, autoalign) 190,397,793: Raw data (X64 model (compressed oops)) 199,205,031: VM Layout Simulation (X64 model (compressed oops)) -0.001% 199,202,303: VM Layout Simulation (X64 model (compressed oops), hierarchy gaps) -0.014% 199,177,791: VM Layout Simulation (X64 model (compressed oops), super gaps) -3.845% 191,544,859: VM Layout Simulation (X64 model (compressed oops), autoalign) -3.846% 191,543,211: VM Layout Simulation (X64 model (compressed oops), hierarchy gaps, autoalign) -3.859% 191,518,687: VM Layout Simulation (X64 model (compressed oops), super gaps, autoalign)

Links