文章目录
- GC
- 如何确定垃圾
- 如何回收垃圾
- 回收垃圾的时机
GC
如何确定垃圾
-
引用计数算法
-
给对象添加一个引用计数器,每当一个地方引用它时,计数器加1,每当引用失效时,计数器减少1,当计数器的数值为0时,也就是对象无法被引用时,表明对象不可在使用。
-
但是这个算法存在一个致命的缺陷,无法解决循环引用的问题。
-
-
根搜索算法
- 这个算法的基本思想是将一系列称为“GC Roots”的对象作为起始点,从这些起始结点开始向下搜索,搜索所走的路径称为引用链。
- 当一个对象到所有的GC root之间没有任何引用链相连时,就认为该对象变成了垃圾。
- GC Roots包含对象:
- 虚拟机栈中引用的对象
- 方法区中的静态属性引用的对象
如何回收垃圾
- 标记清除算法(Mark Sweep)
- 首先标记出所有需要回收的对象,在完成标记后,统一回收掉所有被标记的对象
- 也可以标记存活的对象,统一回收所有未被标记的对象
- 会产生内存碎片
- 标记复制算法
- 一次性回收大片的连续空间
- 内存利用率低,不会产生内存碎片
- 如果说有少量存活对象,复制起来很快,适用于少量对象存活的情况
- 如果有大量对象存活,就需要复制大量对象,效率就低了
- 标记整理算法(Mark Compact)
- 分代收集算法
- 强分代假说
- 熬过越多次垃圾收集过程的对象就越难以消亡。(简单理解就是越老的对象就具有”老而不死”的特性)
- 弱分代假说
- 弱分代假说(Weak Generational Hypothesis): 绝大多数对象都是朝生夕灭的.
- 强分代假说
回收垃圾的时机
- 申请heap space失败后会触发GC回收
- 系统进入idle(休眠)后一段时间会进行回收
- 主动调用GC进行回收
System.gc()