目录
Java JDK7及以前逻辑上被分为三部分:新生代、老年代、永久代 。
Java JDK8及以后被分为了:新生代、老年代、元空间;元空间存储的对象与永久代相同,区别是:元空间并不在jvm中,使用的是本地内存。
为什么要移除永久代?为融合HotSpot JVM与JRockit VM而做出的改变,因为JRockit没有永久代。
将生命周期很短的对象放在新生代,将生命周期很长的对象放在老年代,因为在每次GC时,垃圾回收器都会去判断当前对象是否可以被回收,而这些生命周期很长的对象每次都被垃圾回收器扫描,但每次都不回收,故而可以将这些对象放在老年代,并减少对老年代的GC次数,从而将GC的重心放在新生代上。
通过这两个区域对象的生命周期不同,也可以设置不同的垃圾回收算法,比如对新生代中的对象采用复制算法,因为该区域的对象生命周期短,消亡快,所以当发生GC时并不会存在太多存活的对象,而对老年代则采用标记-清除算法。
精简解释:将对象根据存活概率进行分类,对存活时间长的对象,放到固定区,从而减少扫描垃圾时间及GC频率;针对分类进行不同的垃圾回收算法,对算法扬长避短。
主要为了解决碎片化,因为回收一部分对象后,剩余对象占用的内存不连续,也就是碎片化,过于严重的话,当前连续的内存不够新对象存放就会触发GC,这样会提高GC的次数,降低性能,当S0 GC后存活对象转移到S1后存活对象占用的就是连续的内存。
比如一开始只有Eden区和From中有对象,To中是空的。此时进行一次GC操作,From区中对象的年龄就会+1,我们知道Eden区中所有存活的对象会被复制到To区,From区中还能存活的对象会有两个去处;若对象年龄达到默认年龄为15岁,此时对象会被移动到Old区, 如果Eden区和From区 没有达到阈值的对象会被复制到To区。此时Eden区和From区已经被清空。
这时候From和To交换角色,之前的From变成了To,之前的To变成了From。无论如何都要保证To的Survivor区域是空的。