JVM有哪些垃圾回收算法?
可达性分析法
标记清除算法
拷⻉算法
标记压缩算法
分代收集算法
垃圾回收会经历两个阶段:
标记可回收对象阶段 ->
可达性分析法
垃圾清除阶段 ->
标记-清除算法
标记-拷⻉算法
标记-压缩算法
分代收集算法
标记
可回收对象阶段
- 标记可回收对象阶段使用的算法是
可达性分析法
可达性分析法
: 从 GC Roots 开始向下搜索,搜索所⾛过的路径称为引⽤链。当⼀个对象到 GC Roots 没有任何引⽤链相连时,则证明此对象是不可⽤的,那么虚拟机就判断是可回收对象。可达性分析法
是垃圾回收算法的前提,是非常重要的- 因为垃圾回收算法
主要考察的是清除垃圾阶段
时使用的算法 - 所以
可达性分析法
可以查看我都这篇博客Java基础 -> GC如何判断对象可以被回收
垃圾清除阶段
这个阶段有多个算法,会在不同的情况下选择合适的算法执行 ,这个怎么去选择合适的算法叫分代收集算法
我们会将分代收集算法
放到最后去讲,它集合了所有垃圾回收算法
虚拟机都是使用这个分代收集算法的
MarkSweep 标记-清除算法
:他是最先出现的垃圾回收算法,有着一些考虑不周的情况,存在一些bug
- 算法在标记阶段使用
可达性分析法
- 这种算法是很简单的逻辑,就是把经过
可达性分析法
之后,已经确定为垃圾的对象都删除。 - 他是最先出现的垃圾回收算法,有着一些考虑不周的情况,存在一些bug
- 会产⽣⼤量的内存碎⽚,清除之后内存会很散乱
- 所以有必要其他算法来修复这个bug
- 如下图
Copying 标记-复制算法
:为了解决标记清除算法的内存碎⽚问题,产⽣了拷⻉算法,JVM的新生代都用的拷⻉算法。
- 算法在标记阶段使用
可达性分析法
- 拷⻉算法将内存
分为⼤⼩相等的两半
,每次只使⽤其中⼀半
。 - 垃圾回收时,将当前这⼀块的
存活对象全部复制到另⼀半
,然后当前这⼀半内存就可以直接清除。 - 这种算法没有内存碎⽚,但是他的问题就在于浪费空间。
- ⽽且,他的效率跟存货对象的个数有关。
- 如下图
MarkCompack 标记-整理算法
:为了解决标记-复制算法的缺陷,就提出了标记-整理算法,JVM在老年代默认都是标记-整理算法。
-
算法在标记阶段使用
可达性分析法
-
在完成标记之后,
不是直接清理垃圾内存
-
⽽是将
存活对象往⼀端移动
,然后将端边界以外的所有内存直接清除。 -
如下图
分代收集算法 -> 我们的重点
分代收集算法
: 这个算法并没有新的内容,只是根据对象的存活的时间的长短,将内存分为了新生代和老年代,这样就可以针对不同的区域,采取合适的算法。
- 新生代,每次都有大量对象死亡,有老年代作为内存担保,采取
标记-复制算法
。- 新生代的
Eden区
经过垃圾回收一次后,还存活的对象会被转移到s区
- 新生代s区中,s0,s1这两个区域,内存都是相同大小
- s区经过垃圾回收,对象在s0,s1区域又
来回复制倒腾
- 为什么说有老年代作为内存担保?
- 因为当新生代来回复制对象,内存超了的时候,要么自适应调整新生代内存,要么直接进入老年代
- 新生代的
- 老年代,对象存活时间长,采用
标记-整理,或者标记-清除算法
都可。- 具体使用哪种算法是需要判断老年代用的哪种
垃圾回收器
来决定的 - CMS垃圾回收器 : 主要标记清除算法
- 其他垃圾回收器: 标记整理算法
- 具体使用哪种算法是需要判断老年代用的哪种
- 当垃圾达到阈值(空间担保值),一定以及必定会触发
FullGC
- FullGC 不管你是什么回收器,他是垃圾回收的最后尊严,成败在此一举
- 无论如何怎么整理,怎么垃圾回收,内存都不够了,就说明必须要进行
JVM调优
了 - 单纯的垃圾回收已经不顶用了
点赞,靓仔!!!