注:本专栏文章均为本人原创,未经本人授权请勿私自转载,谢谢。
Java对象的组成部分
-
对象头:在 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)。
-
实例数据:类中所有的实例字段数据。 Java 的基础数据类型所占内存情况如下表格:
boolean byte short char int long float double 1 bytes 1 bytes 2 bytes 2 bytes 4 bytes 8 bytes 4 bytes 8 bytes -
数组长度:这个是数组对象才特有的(4 bytes)。
-
内存填充:该部分作用是用来保证 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