目前主流JVM虚拟机中的垃圾收集器,都遵循分代收集理论:
按照分代收集理论设计的“分代垃圾收集器”,所采用的设计原则:收集器应该将Java堆划分成不同的区域,然后将回收对象依据其年龄(年龄即对象经历过垃圾收集过程的次数——分配到不同的区域存储。
? ? ? ? 如果一个区域中大多数对象都是朝生夕灭(新生代),难以熬过垃圾收集过程的话,把他们集中存储在一起,每次回收时,只关注如何保留少量存活对象,而不是去标记大量将要回收的对象,就能以较低代价回收到大量的空间。
? ? ? ? 如果一个区域中大多数对象都是难以回收(老年代),那么把它们集中放在一起,JVM虚拟机就可以使用较低的频率,来对这个区域进行回收。
? ? ? ? 这样设计的好处是,兼顾垃圾收集的时间开销和内存空间的有效利用。
堆区按照分代存储的好处:
? ? ? ? 在Java堆区划分成不同区域后,垃圾收集器才可以每次只回收其中某一个或者某些区域,所以才有MinorGC、MajorGC、FullGC等垃圾收集类型划分。
? ? ? ? 在Java堆区划分成不同区域后,垃圾收集器才可以针对不同的区域,安排与该区存储对象存亡特征相匹配的垃圾收集算法:标记-清除算法、标记-复制算法、标记-整理算法。
垃圾收集类型划分:
? ? ? ? 该算法分为“标记”和“清除”阶段:首先标记出所有不需要回收的对象,在标记完成后统一回收掉所有没有被标记的对象。它是最基础的收集算法,后续的算法都是对其不足进行改进得到的。
????????“标记-复制”收集算法简称“复制算法”,为了解决“标记-清除”面对大量可回收对象时执行效率低下的问题。
? ? ? ? 该算法将内存分为大小相同的两块,每次使用其中的一块。当这一块的内存使用完后,就将还存活的对象复制到另一块去,然后再把已使用的空间一次清理掉。
? ? ? ? 如果内存中多数对象都是存活的,这种算法将会产生大量的内存见复制的开销,但对于多数对象都是可回收的情况,算法仅需要复制少数存活对象而且每次都是针对整个半区进行内存回收,分配内存时也就不用考虑有空间碎片的复杂情况,只要移动堆顶指针,按顺序分配即可。这样实现简单,运行高效。
? ? ? ? 标记过程仍然与“标记-清除”算法一样,但后续步骤不是直接对可回收对象回收,而是让所有存活的对象像内存空间一端移动,然后直接清理边界以外的内存,这样清理的机制,不会像标记-整理那样留下大量的内存碎片。
? ? ? ? 当前虚拟机的垃圾收集都基于分代收集思想,根据对象存活周期的不同,将内存分为几个不同的区域,在不同的区域使用不同的垃圾收集算法。
? ? ? ? 例如:Heap堆分为新生代和老年代,这样我们就可以根据各个年代的特点选择合适的垃圾收集算法。
? ? ? ? 在新生代中,每次收集都会有大量垃圾对象被回收,所以可以选择“标记-复制”算法,只需要付出少量对象的复制成本就可以完成每次垃圾收集。
? ? ? ? 在老年代中,对象存活几率是比较高的,而且没有额外的空间对它进行分配担保,所以选择“标记-清除”或“标记-整理”算法进行垃圾收集。