JAVA⼀个对象占⽤多少字节
通过代码计算对象的⼤⼩
先说结论:默认16个字节
⼯具JOL :Java Object Layout java对象布局
引⼊POM⽂件
<dependency>
字符串常量nicemeet在内存中占用几个字节<groupId>org.openjdk.jol</groupId>
<artifactId>jol-core</artifactId>
<version>0.10</version>
</dependency>
public class HelloJol {
public static void main(String[] args) {
Object o = new Object();
String s = ClassLayout.parseInstance(o).toPrintable();
System.out.println(s);
}
}
打印结果
前两⾏就是markWord 固定8个字节
分析java对象的组成
普通对象
对象头:markword 8 (锁信息:标识对象的状态,GC信息:对象被回收了多少次分代年龄)
ClassPointer指针:-XX:+UseCompressedClassPointers 为4字节(默认开启) 不开启为8字节 (对象属于哪个Class)
实例数据引⽤类型:-XX:+UseCompressedOops 为4字节(默认开启) 不开启为8字节 Oops Ordinary Object Pointers(成员变量的引⽤⽐如下⾯的Object o)此处的Object o = new Object()没有成员变量,实列数据占0字节
Padding对齐,8的倍数 (64位的机器按块来读,⼀下⼦读16个字节)
所以Object o = new Object()占⽤字节如下
16个字节=对象头8+ClassPoint指针 4+实列数据0+padding对其4 = 16个字节
数组对象
对象头:markword 8
ClassPointer指针同上
数组长度:4字节
数组数据:
padding对齐 8的倍数
⽤例测试
public class T03_SizeOfAnObject {
public static void main(String[] args) {
System.out.println(ObjectSizeAgent.sizeOf(new Object()));
System.out.println(ObjectSizeAgent.sizeOf(new int[] {}));
System.out.println(ObjectSizeAgent.sizeOf(new P()));
}
//⼀个Object占多少个字节
// -XX:+UseCompressedClassPointers -XX:+UseCompressedOops
// Oops = ordinary object pointers
private static class P {
//8 _markword
//4 _class pointer
int id; //4
String name; //4
int age; //4
byte b1; //1
byte b2; //1
Object o; //4
byte b3; //1
}
}
打印结果:
16 = 对象头8个 + ClassPointer指针 4个 +padding对齐 4个
16 = 对象头8个 + ClassPointer指针 4个 +数组长度 4个 +padding对齐0个
32 = 对象头8个 + ClassPointer指针 4个 + int id 4个 + name的引⽤四个 + int age 4个+1+1+4+1 + padding对齐
对象头具体包括什么
8个字节64位看对象的状态分配64位。普通状态和锁定状态每⼀位完全不⼀样
主要包括
锁的标识位:标识对象的状态,
GC标记:对象被回收了多少次分代年龄
当⼀个对象已经计算过identity hash code它就⽆法进⼊偏向锁状态
对象是怎么定位的
T t = new T()
t是怎么到堆内存中的T对象
1.间接⽅式句柄池:t指向了⼀个结构体也就是句柄池(图中如评论所说,画错了)
这个结构体有两个指针,分别指向T对象和T.class。好处是对象挪动t位置不变,垃圾回收效率⾼
2.直接指针(HotSpot的实现):T对象⾥⾯除了包括⾃⼰的成员变量之外还包括了类型指针。好处是快⼀下⼦定位。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论