Java对象的结构分析

155 阅读4分钟

注:本专栏文章均为本人原创,未经本人授权请勿私自转载,谢谢。

Java对象的组成部分

  1. 对象头:在 JVM 中每一个 Java 对象都有一个对象头,对象头中包含标记字段以及对象指针,标记字段用来储存 hash 码、GC 信息以及锁信息,而指针则指向该对象的类。在64位 JVM 中这两部分都是 64 位的,所以也就是需要 128 位大小(16 bytes)。

    注意:64 位虚拟机中在堆内存小于 32 GB 的情况下,指针压缩(UseCompressedOops)是默认开启的,会将原来 64 位的指针压缩为 32 位(由于 JVM 有内存对齐机制,其内存的地址都是 8 的整数倍,故:指针压缩后的值*8 + JVM 内存偏移 = 内存真实值),所以指针压缩后需要 64 + 32 = 96 位(12 bytes)。

  2. 实例数据:类中所有的实例字段数据。 Java 的基础数据类型所占内存情况如下表格:

    booleanbyteshortcharintlongfloatdouble
    1 bytes1 bytes2 bytes2 bytes4 bytes8 bytes4 bytes8 bytes
  3. 数组长度:这个是数组对象才特有的(4 bytes)。

  4. 内存填充:该部分作用是用来保证 Java 对象在虚拟机中占内存大小为 8*N bytes。

使用 JOL 工具分析 Java 对象大小

pom.xml

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

Java 测试代码:

static class User {
    private byte gender;
    private String name;
​
    public byte getGender() {
        return gender;
    }
​
    public void setGender(byte gender) {
        this.gender = gender;
    }
​
    public String getName() {
        return name;
    }
​
    public void setName(String name) {
        this.name = name;
    }
}
​
public static void main(String[] args) throws Exception {
    System.out.println(ClassLayout.parseInstance(new Object()).toPrintable());
    System.out.println(ClassLayout.parseInstance(1.2).toPrintable());
    System.out.println(ClassLayout.parseClass(User.class).toPrintable());
    System.out.println(ClassLayout.parseInstance(User.class).toPrintable());
}

输出:

java.lang.Object object internals:
 OFFSET  SIZE   TYPE DESCRIPTION                               VALUE
      0     4        (object header)                           01 00 00 00 (00000001 00000000 00000000 00000000) (1)
      4     4        (object header)                           00 00 00 00 (00000000 00000000 00000000 00000000) (0)
      8     4        (object header)                           58 0d 00 00 (01011000 00001101 00000000 00000000) (3416)
     12     4        (loss due to the next object alignment)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
​
java.lang.Double object internals:
 OFFSET  SIZE     TYPE DESCRIPTION                               VALUE
      0     4          (object header)                           01 00 00 00 (00000001 00000000 00000000 00000000) (1)
      4     4          (object header)                           00 00 00 00 (00000000 00000000 00000000 00000000) (0)
      8     4          (object header)                           78 da 04 00 (01111000 11011010 00000100 00000000) (318072)
     12     4          (alignment/padding gap)                  
     16     8   double Double.value                              1.2
Instance size: 24 bytes
Space losses: 4 bytes internal + 0 bytes external = 4 bytes total
​
com.kanra.test.structs.ListNodeTest$User object internals:
 OFFSET  SIZE               TYPE DESCRIPTION                               VALUE
      0    12                    (object header)                           N/A
     12     1               byte User.gender                               N/A
     13     3                    (alignment/padding gap)                  
     16     4   java.lang.String User.name                                 N/A
     20     4                    (loss due to the next object alignment)
Instance size: 24 bytes
Space losses: 3 bytes internal + 4 bytes external = 7 bytes total
​
java.lang.Class object internals:
 OFFSET  SIZE                                              TYPE DESCRIPTION                               VALUE
      0     4                                                   (object header)                           01 e0 eb 66 (00000001 11100000 11101011 01100110) (1726734337)
      4     4                                                   (object header)                           63 00 00 00 (01100011 00000000 00000000 00000000) (99)
      8     4                                                   (object header)                           28 17 00 00 (00101000 00010111 00000000 00000000) (5928)
     12     4                                               int Class.classRedefinedCount                 0
     16    24                                                   (alignment/padding gap)                  
     40     4                     java.lang.reflect.Constructor Class.cachedConstructor                   null
     44     4                                  java.lang.String Class.name                                (object)
     48     4                                  java.lang.Module Class.module                              (object)
     52     8                                                   (alignment/padding gap)                  
     60     4                                  java.lang.String Class.packageName                         (object)
     64     4                                   java.lang.Class Class.componentType                       []
     68     4                       java.lang.ref.SoftReference Class.reflectionData                      (object)
     72     4   sun.reflect.generics.repository.ClassRepository Class.genericInfo                         null
     76     4                                java.lang.Object[] Class.enumConstants                       null
     80     4                                     java.util.Map Class.enumConstantDirectory               null
     84     4                    java.lang.Class.AnnotationData Class.annotationData                      (object)
     88     4             sun.reflect.annotation.AnnotationType Class.annotationType                      null
     92     4                java.lang.ClassValue.ClassValueMap Class.classValueMap                       null
Instance size: 96 bytes
Space losses: 32 bytes internal + 0 bytes external = 32 bytes total

发布于 2022-08-20 22:04