堆内存的模型:
新生代的GC
新生代:新生代分为Eden区和Survivor区,分配比例为8:2;而Survivor区又1:1分为from区和to区。这样分配的理由是,新生代中的对象存活率低,大概只有10%。
这种情况下新生区采用的GC算法是:复制算法,我们知道复制算法最大的弊端就是内存的浪费,但是在低存活率的新生区。只需要空余10%的内存进行效率高的复制算法也是划算的。在第一次GC之前,对象的创建是Eden区域,当Eden区满时,会进行第一次GC,将Eden区的存活对象复制到From区域,如果from区域不足,其他存活对象进入老生代,将Eden区域进行回收。第二次GC前,对象的创建还是Eden区,当Eden区满时,进行第二次GC,将Eden区和From区中的存活对象复制到to区,to区不足时,其他存活对象进入老生代,将Eden区域进行GC。
每次复制算法保证有一个Survivor区的空余。
对象进入老生代的两种方式:
1.熬过GC的次数到达一定时(在from区、to区之间反复的次数)进行老生代,次数可以在虚拟机中配置。
2.Eden区域的存活对象不能溢出了Survivor区,溢出的部分也会进入老生代。
老生代的GC
- 老生代:进入老生代的对象存活率太高,不适合用复制算法,会浪费大量的内存空间而且溢出的对象无处可去。所以在老生代中使用的是标记-整理和标记-清除两种算法。
- 利用标记-整理算法来保证内存的连续性
- 利用标记-清除算法来保证GC的效率