目录
1、分代收集理论
现在的垃圾收集器基本都遵循了“分代收集”的理论
弱分代假说:大多数对象都是朝生夕死的(就是利用完基本就是死了)
强分代假说:熬过越多次垃圾收集过程的对象就越难以消亡。
把分代理论放到虚拟机里就形成了我们经常听到的老年代和新生代两个区域,每次垃圾回收都会有大量的对象死去,而活下来的对象就会逐渐放到老年代中去,这就是上面说的强分代假说。
但是实际中对象的死活不不仅仅是分代这么简单,例如:老年代中的对象指引到新生代中,如果回收新生代的对象,就会造成老年代中对象指向的丢失。由引出了第三条假说
跨代引用假说。
2、收集算法
(1)标记—清除算法(适用老年代)
这是最早最基础的算法,首先标记出要回收的对象,标记完成,统一回收被标记的对象,当然也可以反着说(标记不需要回收的,回收没被标记的)
缺点:1、执行效率不稳定,随着对象数量的增多,标记次数增多,清楚也变多,执行效率下降2、内存空间碎片化,假如说被清除和保留的对象内存交错在一起,就会导致内存空间碎片化,即使空间充足,由于碎片化也没法新建对象,导致空间浪费。
(2)标志—复制算法(适用于新生代)
他实现原理是把内存空间分成两块空间,将存活的对象复制到另一块空间,假如说大量的对象被回收,只需要复制一小部分即可,所以适用于新生代。(速度快,效率高)
缺点:代价是明显的需要浪费一半的空间
后面针对对象朝生熄灭的特点衍生更好的半区复制策略——“Appel”式回收,具体的策略为,将新生代空间分为一块较大Eden的空间和两块较小Survivor,其中HotSpot虚拟机默认的比例是Eden:Survivor=8:1,也就是说每次新生代拥有90%的空间(Survivor80+Eden10),大大减少了空间浪费,同样也会有这样的问题,假如说总共100MB空间 ,此次回收对象为20MB,很显然,剩下的10MB无法占下,谁都不能保证这种情况不会发生,这时Appel采用了“逃生门”设计——内存分配担保
内存分配担保
就是将Survivor无法站下的那部分直接放入老年代。就是相当于把上面例子中的20MB直接放入老年代。
(3)标记—整理算法(适合老年代)
与标记—清除不同的是,将存活的对象标记后,没有进行直接清除而是将存活的对象向一端整理到一起,这样就解决了空间碎片化问题,因为老年代的特点所以只有很少一部分被清除。在老年代会有大量的活对象,并且需要更新对象索引,这就导致了系统的负重,并且这种对象一定操作必须在系统停止的情况下进行,这是就出现了我们经常听到的““Stop The World”
另外还有一种和稀泥走一步看一步的方法,就是平常的时候采用标记清除法,产生碎片化后,直到影响到对象分配时,再采用标记整理法,以获得完整的空间。基于标记—清除的算法的CMS收集器就是采用的这种处理方法。