1.对象的创建流程
1.1检查该类是否由类加载器加载到jvm中,如果加载过则不重复加载,直接使用,没有加载的话,那么直加载到jvm中
1.2 给对象分配内存
1.3 对象中的静态变量初始化,执行静态代码块
1.4 设置对象头,包括markwork,classpoint,padding
1.5 init
2.如何给对象划分内存
2.1 指针碰撞:记录对象在内存分配的最后位置,然后指针移动到下一个空闲空间
2.2 空闲列表: jvm垃圾回收后,内存空间并不是连续的,如果碰到大对象的话,有没有连续的
空间,则在剩下的大空间划分一块空闲空间来存放
3.对象并发分配
3.1 cas分配
3.2 tlab: ThreadLocal allocation buffer:本地线程分配缓存,也就是说每个线程栈有一个私有的
的小空间共对象来存放,大概占用栈空间的1%,如果存放个的下则直接存放在该空间里
4.对象在内存的具体分配
<dependency>
<groupId>org.openjdk.jol</groupId>
<artifactId>jol‐core</artifactId>
<version>0.9</version>
</dependency>
引入该依赖来分析对象在内存的分配情况
压缩指针:节省空间,默认开启
注意:堆内存大于32G时,压缩指针会失效,强制使用64位来寻址,由于硬件厂商的原因导致寻址最大只能达到48位,包括数据总线,地址总线,
栈上分配:效率高,直接入栈出栈即可不需要gc,方法中的变量只在本方法使用,则不会发生逃逸
栈上分配依赖于逃逸分析和标量替换,所以一定要开启逃逸分析和标量替换
5.大对象直接进入老年代,防止大对象在新生代频繁yong gc,直接进入老年代可以提高效率
6.长期存活的对象将进入老年代,也是防止长期存活对象在新生代频繁yong gc,直接进入老年代可以提高效率
7.对象动态年龄判断:也就是eden gc的时候,eden分配不下的对象要在s0区分配,如果eden要需要60M的空间,但是eden不够,同时s0和s1都是100M的空间,此时s0区域可以存放,但是由于对象动态年龄判断机制,直接会把该60M对象存放到老年代,这就是对象动态年龄的判断机制
8.老年代空间分配担保机制
某个时刻年轻代要yong gc,当时yong gc之前回去老年代查看老年代的空间是否存的下年轻代的对象,如果存的下那么直接yong gc,如果存不下,首先会做一次full gc,那么经过full gc后就可以存的下yong gc的对象,如果不做full gc,直接yong gc,此时对象进入老年代存放不下就会full gc,这样的效率反而不如直接 full gc的效率高,这就是老年代空间分配担保机制