jvm - 内存空间提到了,建立对象的时候,对象是在堆内存中建立的。但堆内存又分为新生代和老年代,新生代又细分Eden空间、From Survivor空间、To Survivor空间。咱们建立的类到底在哪里?jvm
堆内存分为新生代和老年代,新生代是用于存放使用后准备被回收的对象,老年代是用于存放生命周期比较长的对象。大部分咱们建立的对象,都属于生命周期比较短的,因此会存放在新生代。新生代又细分Eden空间、From Survivor空间、To Survivor空间,咱们建立的对象,对象优先在Eden分配。
随着对象的建立,Eden剩余内存空间愈来愈少,就会触发Minor GC
,因而Eden的存活对象会放入From Survivor空间。Minor GC
后,新对象依然会往Eden分配。
Eden剩余内存空间愈来愈少,又会触发Minor GC
,因而Eden和From Survivor的存活对象会放入To Survivor空间。性能
在上面的流程中,若是一个对象很大,一直在Survivor空间复制来复制去,那很费性能,因此这些大对象直接进入老年代。能够用XX:PretenureSizeThreshold来设置这些大对象的阈值。spa
在上面的流程中,若是一个对象Hello_A,已经经历了15次Minor GC
还存活在Survivor空间中,那他即将转移到老年代。这个15能够经过-XX:MaxTenuringThreshold来设置的,默认是15。虚拟机为了给对象计算他到底经历了几回Minor GC
,会给每一个对象定义了一个对象年龄计数器。若是对象在Eden中通过第一次Minor GC后仍然存活,移动到Survivor空间年龄加1,在Survivor区中每经历过Minor GC后仍然存活年龄再加1。年龄到了15,就到了老年代。code
除了年龄达到MaxTenuringThreshold的值,还有另一个方式进入老年代,那就是动态年龄判断:在Survivor空间中相同年龄全部对象大小的总和大于Survivor空间的一半,年龄大于或等于该年龄的对象就能够直接进入老年代。
好比Survivor是100M,Hello1和Hello2都是3岁,且总和超过了50M,Hello3是4岁,这个时候,这三个对象都将到老年代。对象
上面的流程提过,存活的对象都会放入另一个Survivor空间,若是这些存活的对象比Survivor空间还大呢?整个流程以下:blog