你未必出类拔萃,但一定与众不同
垃圾收集算法
从如何判定对象消亡的角度出发,垃圾收集算法可以分为 “引用计数式垃圾收集”和“追踪式垃圾收集”
以下都是追踪式垃圾收集范畴
分代收集理论
当前的垃圾收集器大多都遵循了“分代收集” 的理论进行设计
主要建立在两个分代假说上
- 弱分代假说 :绝大多数对象都是朝生夕死的
- 强分代假说: 熬过越多次垃圾收集过程的对象就越难以消亡
- 跨代引用假说: 跨代引用相对于同代引用来说仅占极少数(新生代建立记忆集)
注意
- 部分收集(Partial GC):指目标不是完整收集整个Java堆的垃圾收集,其中又分为
- 新生代收集(Minor GC/Young GC):指目标只是新生代的垃圾收集
- 老年代收集(Major GC/Old GC):指目标只是老年代的垃圾收集 目前只有CMS收集器会有单独收集老年代的的行为
- 混合收集(Mixed GC):指目标是收集整个新生代以及部分老年代的垃圾收集,目前只有G1收集器会有这种行为
- 整堆收集(Full GC):收集整个Java堆和方法区
标记-清除算法
算法分为标记和清除两部分
首先标记出所有需要回收的对象,在标记完成后,回收所有被标记的对象 标记过程就是对象是否是垃圾的判定过程
两大缺点
- 执行效率不稳定 如果堆中含有大量对象,且其中大量对象都是需要回收的 这时就需要进行大量标记和清除的动作,导致效率急速下降
- 内存空间的碎片问题 标记清除后会产生大量的不连续的内存碎片,导致在分发大对象的时候找不到足够的空间而不得不提前触发另一次垃圾收集动作
- 以下为图解 上为回收前状态 下为回收后状态
标记-复制算法
简称复制算法 用来解决标记清除算法面对大量可回收对象执行效率低的问题
将可用内存划分为大小相等的两块。每次只使用其中一块,一块内存空间用完了,就将还存活的对象复制到另外一块上,然后把使用的那块对象一次性清除掉
缺点
- 将可用内存空间缩小为原来的一半,空间浪费大
以下为图解 上为回收前状态 下为回收后状态
标记-整理算法
标记复制算法在对象的存活率过高的时候,需要频繁进行复制操作,降低效率
关键的是 不想要浪费50%的空间就需要有额外的空间进行担保,以便应对100%的对象都存活的情况,所以老年代不能使用这种算法
标记清除和标记整理的本质区别就是前者是一种非移动式样的回收算法 后者则是移动的
让所有存活的对象都向内存空间一端移动,然后直接清除掉边界以外的内存。
以下为图解 上为回收前状态 下为回收后状态