代码工具:jol

代码工具:jol

Posted by BY on November 27, 2019

代码工具:jol

JOL(Java对象布局)是用于分析JVM中的对象布局方案的微型工具箱。这些工具大量使用Unsafe,JVMTI和Serviceability Agent(SA)来解码实际的 对象布局,占用空间和引用。这使得JOL比依赖堆转储的其他工具更加准确。

作为maven包引入

OpenJDK社区将这些发行版本定期地推送到Maven Central,你可以通过在pom中添加以下的依赖项来使用它:

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

在使用之前建议你先看下 JOL SamplesCLI tools source

作为命令行工具

如果你是通过源代码构建的JOL,那么会生成一个可执行JAR包 jol-cli/target/jol-cli.jar。已发布在Maven的组件也包含这个JAR,您可以立即下载并开始使用它。请在此处查找最新版本。

以下是我们的简要操作清单:

  • 获取对象的内部信息,即对象内的字段布局,标题信息,字段值,对齐损失数据。
$ 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
  • 获取对象的externals,即从实例可访问的对象,它们的地址,通过可达性图的路径等:
$ 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]

获取对象 footprint 估算值,与获取对象的externals元素相同,但列表如下 :

$ 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)
  • 获取不同VM模式下的对象布局(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
  • 使用堆转储计算在不同VM模式下可感知的占用空间(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)