对象的创建过程
- class loading
- class linking
- verification:校验class文件是否符合JVM规范;
- preparation:将静态的成员变量赋默认值;
- resolution:将类、方法、属性等符号引用解析为直接引用;常量池中的各种符号引用解析为指针、偏移量等内存地址的直接引用。
- initializing:将静态成员变量赋初始值。
- 申请内存
- 成员变量赋默认值
- 调用构造方法<init>
- 成员变量顺序赋初始值
- 执行构造方法语句
数对象在内存的存储布局
new了之后,对象在内存的存储布局是怎样的呢?普通对象与数组对象在内存中的存储布局有稍稍不同。
简单来说,数组对象比普通对象多了数组长度这一项。
普通对象
- 对象头 markwork :8byte
- ClassPointer指针:默认 8 byte;使用 -XX:+UseCompressedClassPointers,则4 byte
- 实例数据
- 引用类型:默认 8 byte;使用-XX:+UseCompressedOops,则4字节
- Oops:Ordinary Object Pointers
- padding对齐 :字节大小为8的倍数
数组对象
- 对象头 markwork :8byte
- ClassPointer指针:默认 8 byte;使用 -XX:+UseCompressedClassPointers,则4 byte
- 数组长度
- 数组数据
- padding对齐:字节大小为8的倍数
对象头包括什么
对象头,即markwork。那么这markwork里有什么呢?markwork里中记录了锁以及GC的信息。
markwork的具体信息
markwork.png关于hashcode的冷门小知识
hashcode有两种情况,一种是重写了hashcode,return了一个固定值,另一种则是hashcode根据存储布局的大小来计算。
如果对象已经计算了hashcode的值,变成IdentityHashCode后,是无法变成偏向锁
对象如何定位
对象的定位方式有两种,一种是句柄池,另一种则是直接指针。
对象的定位方式需要看JVM的具体实现。目前,在Hotspot中,对象的定位方式是直接指针。
句柄池和直接指针有什么区别?句柄池比直接指针定位要快,但是直接指针有利于GC的回收。
一些不怎么重要的小知识
- java8大原子操作:虚拟机规范,已废弃
- happen-before:虚拟机规范
- as if serial:不管指令如何重排序,单线程的结果是不会变的
- 观察虚拟机的配置:java -XX:+PrintCommandLineFlags -version
网友评论