对象的内存布局
对象的创建
Object o = new Object();
内存中有一个变量o指向new出来的对象,
蓝色区域代表的就是对象。
半初始化问题
通过new创建对象时分为三步:
第一步申请分配内存,这一步给成员变量赋默认值,
第二步调用构造方法,这一步给成员变量赋初始值,
第三步建立指针与对象的关联。
第二步是为了解决c++ 变量遗留值的问题,
是上一个程序访问过这块空间遗留下的值,安全起见先赋默认值。
对象的布局
普通对象
分为4个部分:
markword
8个字节
class pointer
4个或8个字节,指向对应的class
instance data
对象的内部数据,例如成员变量
padding
将字节数长度拼接到可以被8整除
<!-- https://mvnrepository.com/artifact/org.openjdk.jol/jol-core -->
<dependency>
<groupId>org.openjdk.jol</groupId>
<artifactId>jol-core</artifactId>
<version>0.16</version>
<scope>provided</scope>
</dependency>
ObjectLayout
package com.duohoob.jvm.bytecode;
import org.openjdk.jol.info.ClassLayout;
@SuppressWarnings("unused")
public class ObjectLayout {
private static class T {
int a, b;
}
public static void main(String[] args) {
T t = new T();
System.out.println(ClassLayout.parseInstance(t).toPrintable());
}
}
运行
com.duohoob.jvm.bytecode.ObjectLayout$T object internals:
OFF SZ TYPE DESCRIPTION VALUE
0 8 (object header: mark) 0x0000000000000001 (non-biasable; age: 0)
8 4 (object header: class) 0xf800c043
12 4 int T.a 0
16 4 int T.b 0
20 4 (object alignment gap)
Instance size: 24 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
数组
多了个数组长度
对象头包含什么
对象头包含markword、class pointer信息,
markword包含hashCode信息、synchronized锁信息、GC垃圾回收标记。
GC标记包含三色标记信息和分代年龄。
对象的定位
直接指针
堆中的是实例对象,方法区中的是类型class。
间接指针
优点:垃圾回收不用频繁改动t。
缺点:慢,需要先定位到指针,再定位到对象,两次访问。
对象的分配
函数内的局部变量,
new的时候会先尝试在自己的栈帧内部分配空间,
例如for循环内通过new创建对象,
方法执行完毕,栈帧自动弹出,释放掉空间。
逃逸分析
分析函数内部的创建出的对象,
除了当前栈帧还有没有被其它栈帧调用,
是否逃出了当前栈帧管控范围,
如果有则不能再栈上分配,只能分配在堆上。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。