一、Java虚拟机对象的创建
遇到new指令时:
1. 在方法区中看该类是否已经被加载,看类是否被加载、解析和初始化,如果没有,则先加载这个类。
2. 为类分配空间,如果堆中的内存是连续的,则用指针碰撞的方法找到一块连续的区域;如果是不连续的,则用空闲链表法,找到一块空间;
3. 找到空间之后,为了避免并发等问题,有两种办法:
- 将采用CAS机制保证更新操作的原子性
- 将内存分配的动作按照线程分配到不同的空间之中,每个线程在堆中都有一块自己的小内存(本地线程分配缓冲),只有当自己的空间用完时,才用同步的方式分配内存。
4. 生成对象头信息。包括类信息,hashcode,分代信息,锁信息等。至此,一个对象已经产生了,但是所有的字段还没有初始化。
5. 对对象执行init方法,执行初始化,对字段赋值。
二、对象的内存布局
主要包括对象头,实例数据 和对齐填充
对象头
一部分是运行时数据(MarkWord),包括hashcode,GC年龄分代,锁状态信息,持锁的线程,线程id
另一部分是类型指针,指向类元数据的指针。数组例外,这个地方存的是数组的长度
实例数据
这部分存的是对象的有效信息。不管是父类继承的还是自己的。
会根据内存分配策略对各个字段进行分配,默认占用空间从大到小。
long/double ----> int ----> shorts/chars ----> bytes/booleans ----> 对象引用
填充信息
当不够一个字的时候(32或者64),补齐。
三 对象的访问定位
1.句柄 有一个句柄池,每一个句柄都包含两个地址指针,一个指向堆中的对象,一个指向方法区中的类信息
2.直接地址 通过地址访问
网友评论