上篇文章主要讲了对象的定位,以及jdk的优化技术逃逸分析和标量替换,这样的新技术出现,就导致java对象实例都分配在堆内存里面也变得不是那么的绝对了。
对象的分配过程如下:
方法里面开始new一个对象,即时编译器会对这个对象的动态作用域进行分析,如果满足逃逸分析和标量替换的条件,并启用了标量替换,那么就在当前栈帧里面去分配对象,等待方法执行完毕,随着方法的出栈,此对象也就消失了。如果不满足要求,那么会分配到堆内存里面,分配之前会判断,如果对象的大小太大了(jvm调优里面有个参数XX:PretenureSizeThreshold控制对象体积的阀值),就会直接分配到老年代(避免大对象在年轻代来回拷贝),在老年代里面等待FullGC回收;如果对象不是很大,就会分配到年轻代的eden区,第一次垃圾回收后,对象进入幸存者区,接着等待垃圾回收,垃圾回收的时候对象会在幸存者区里面的from和to两者之间来回拷贝,每换一次位置,对象的年龄就加1,等到年龄满15之后(CMS默认为6),对象就进入老年代;进入老年代之后就等待着老年代的垃圾回收器接着回收,知道生命周期结束。如下图所示:
将新生对象直接分配到eden区的时候,其实jdk做了一些优化的,就叫TLAB,啥意思呢,TLAB的全称是:Thread Local Allocation Bu