一.垃圾收集算法
1.分代收集理论
根据对象存活的周期不同将内存分为几块,分为年轻代和老年代,在年轻代中每次回收接近99%的对象,所以选择复制算法,老年代存活概率高,空间小,选择标记清除或者整理。
2.标记复制算法
将内存分为两块,每次只使用其中一块,当这块 内存用满时,会进行回收,将存活的对象移动到另一块,清理之前的那块
缺点:只能使用一半的内存,使用空间小
3.标记清除算法
将可回收或者存活对象标记,清除可回收对象
缺点:标记成本较大,可能标记的太多了,清除之后会产生内存碎片,内存不规整
4.标记整理算法
和标记清除的区别就是清理完之后会整理内存空间
二.垃圾收集器
1.Serial收集器(单线程收集器)
缺点:单线程,进入GC的时候,程序会STW
2.Parallel Scavenge收集器(Serial收集器多线程版本)jdk1.8默认的垃圾收集器
新生代采用复制算法,老年代采用标记-整理算法。
缺点:依然会STW,但STW时间短暂些,GC过程时间短,程序吞吐量高
3.ParNew收集器
ParNew收集器其实
跟Parallel收集器很类似
,区别主要在于它可以和CMS收集器配合使用。
新生代采用复制算法,老年代采用标记-整理算法。
![](https://img-blog.csdnimg.cn/cc0d4fe1d9084d35aaae6320167c4ff8.png)
4.CMS收集器
以减少stw为核心的收集器,注重用户体验,使用标记清除算法
初始标记:stw,记录gc roots直接引用的对象
并发标记:用户线程和垃圾收集线程一起运行,因为用户线程还在运行,可能有一些标记过的发生了改变
重新标记:修正并发标记期间因为用户程序运行导致标记发生变动的那一部分对象的标记记录,这个阶段会有STW。
并发清理:开启用户线程,GC线程对未标记区域清扫
并发重置:重置本次的标记数据
从它的名字就可以看出它是一款优秀的垃圾收集器,主要优点:
并发收集、低停顿
。但是它有下面几个明显的缺点:
对CPU资源敏感(会和服务抢资源);
无法处理
浮动垃圾
(在并发标记和并发清理阶段又产生垃圾,这种浮动垃圾只能等到下一次gc再清理了);
它使用的回收算法-
“标记-清除”算法
会导致收集结束时会有
大量空间碎片
产生,当然通过参数-
XX:+UseCMSCompactAtFullCollection可以让jvm在执行完标记清除后再做整理
执行过程中的不确定性,会存在上一次垃圾回收还没执行完,然后垃圾回收又被触发的情况,
特别是在并
发标记和并发清理阶段会出现
,一边回收,系统一边运行,也许没回收完就再次触发full gc,也就是"
concurrent
mode failure
",
此时会进入stop the world,用serial old垃圾收集器来回收