by shihang.mai
JMM就是java内存模型,它描述了对象的内存布局、如何访问变量、线程的共享变量访问规则、对象分配等等
1. 对象的内存布局
在hotspot中,对象需要知道自己的类型,所以对象组成中有ClassPointer(类型指针)
-
普通对象
普通对象内存布局.png -
数组对象
数组对象内存布局.png
2. 对象大小
2.1 压缩指针
运行
java -XX:+PrintCommandLineFlags -version
得到
-XX:InitialHeapSize=134217728
-XX:MaxHeapSize=2147483648
-XX:+PrintCommandLineFlags
//开启压缩 类型指针
-XX:+UseCompressedClassPointers
//开始压缩 引用类型
-XX:+UseCompressedOops
-XX:+UseParallelGC
java version "1.8.0_251"
Java(TM) SE Runtime Environment (build 1.8.0_251-b08)
Java HotSpot(TM) 64-Bit Server VM (build 25.251-b08, mixed mode)
可以看到开启了压缩指针
- 压缩指针存在的意义
我们由32位计算机变为64位,虽然我们能获得的内存大了(寻址空间从2^32 次方,变为2^64次方),但是同一个对象存在堆里会花费更多的空间(类型指针和对象引用都变为了8字节)。在64位下会带来性能问题
-
增加了GC开销:64位对象引用需要占用更多的堆空间,留给其他数据的空间将会减少,从而加快了GC的发生,更频繁的进行GC
-
降低CPU缓存命中率:CPU缓存是固定大小的,64位对象引用增大了,CPU能缓存的oop将相对减少会,从而降低了CPU缓存的效率
我们开启指针压缩,可以同时获得较大的内存,也能保持32位的性能
- 压缩指针的实现方式
首先有一个预备消息,32位CPU为什么支持最大4G?准确来说,应该是32位CPU为什么寻址容量为4G?
- CPU一次性读取4字节数据,即32位
- 4字节代表232个地址,而内存的最小IO单位是字节,其实这个232是【由8bit组成的一组的】地址数
- 所以实际寻址容量 = 2^32 * 8 = 2^35 = 4G
待研究,没研究清楚
2.2 对象大小举例
-
new Object():16byte
对象头:8byte ClassPointer:4byte(64位计算机,原本是8字节,上面打开了-XX:+UseCompressedClassPointers压缩,所以4字节) padding:4字节(整个对象是8的倍数,8+4=12,+4=16)
-
数组 new int[]{}:16byte
对象头:8byte ClassPointer:4byte(64位计算机,原本是8字节,上面打开了-XX:+UseCompressedClassPointers压缩,所以4字节) 数组长度:4字节
-
new P():32byte
class p{ //对象头:8byte //ClassPointer:4byte int id;//int:4byte String name;(64位计算机,原本是8字节,上面打开了-XX:+UseCompressedOops 压缩(oops:普通对象的指针),所以4字节) int age; byte b1;//byte:1byte byte b2; Object o; byte b3; }
3. 对象头具体包括什么
markword锁不同的锁状态包括的东西不一样,但是:
- 用2bit表示对象是否被锁定。再无锁态和偏向锁时,需要再看一bit
- 用4bit表示GC分代年龄,4bit最大可以表示为15(2进制:1111),所以GC年龄默认15,最大15.
ps:当一个对象计算过identityHashCode(没重写hashcode,调用了默认的)后,不会进入偏向锁状态
4. 对象的定位
-
句柄池
句柄池 -
直接指针
直接指针
5. 对象如何分配
对象分配- 先看能不能在栈上分配。这里涉及逃逸分析,当没方法逃逸时,即可栈上分配。
- 如果能在栈分配,那么分配。如果不能栈分配,那么看对象大不大,如果大,直接在old区分配。
- 如果不大,那么会进行TLAB在自己的线程在eden区特有的区域分配
- 然后经过GC回收,如果达到一定条件,进入old区
参考
https://blog.csdn.net/liujianyangbj/article/details/108074167#comments_15280876
https://blog.csdn.net/liujianyangbj/article/details/108049482
网友评论