JVM垃圾回收算法和垃圾回收器是什么?
垃圾回收算法
- 复制算法(Copying)
- 标记-清除算法(Mark-Sweep)
- 标记-整理算法(Mark-Compact)
复制算法:
优点,效率高,不会出现内存碎片,
缺点,内存利用率低,只能用一半,存活对象较多时效率明显下降
Eden from to 8:1:1,java中大部分对象朝生夕死,所以只有10%的对象需要回收,10%(from)+ 10%(to,预留)
标记清除算法:
优点:空间利用率100%
缺点:标记和清除效率都不高,会产生大量不连续的内存碎片
过程:1.首先标记所有需要回收的对象 2.统一回收被标记的对象
标记整理算法:
优点:利用率100%,没有内存碎片
缺点:标记和清除效率都不高,效率相对标记-清除要低
过程:标记后不直接进行清理,而是把存活对象向一端移动,然后清理端边界外的内存。垃圾回收器
分代算法:根据各个年代特点选用不用垃圾回收算法
新生代:采用复制算法
老年代:使用标记-整理或标记-清除算法
并行:垃圾收集的多线程同时进行
并发:垃圾收集的多线程和应用的多线程同时进行
回收器
1,Seral/Serial Old : 单线程
2,ParNew: 和Seral基本没区别,多线程
3,Parallel Scavenge(ParallerGC)/Parallel Old : 关注吞吐量的收集器,主要用于后台运算而不需要太多交互的任务。
4,CMS:一种最短停顿时间的收集器。使用标记清除算法
5,G1:jdk1.9以后推荐使用,跨越的新生代和老年代。使用标记整理和化整为零
所有新生代都是用复制算法,老年代 标记整理和标记清除
Concurrent MarkSweep(CMS):
-XX:+UseConcMarkSweepGC,应用于B/S系统服务器,重视服务的响应速度,希望系统停顿时间最短,给用户较好的体验。
垃圾回收过程:
- 初始标记:仅标记GC Roots直接关联的对象,速度快,需要停顿
- 并发标记:从GC Roots对象进行可达性分析,找到存活对象,耗时最长,不需要停顿
- 重新标记:修改并发标记期间因程序继续运作导致标记变动那一部分,需要停顿(STW),这个停顿会比初始标记长一些,但比并发标记时间短
- 并发清除:不需要停顿
优点:耗时最长的并发标记和并发清除可以与用户线程一起工作。
缺点:
1,CPU资源敏感:并发暂用CPU资源,CPU不足,效率明显降低。
2,浮动垃圾:并发清理阶段,由于用户线程继续运行产生的垃圾,CMS无法处理,需等待下一次GC处理,这部分成为"浮动垃圾"
3,会产生空间碎片:标记-清理算法会产生不连续的空间碎片G1垃圾收集器
-XX:+UseG1GC
内部布局改变
G1把堆划分多个大小相等的独立区域(Region),新生代和老年代不再物理隔离。
算法:标记-整理(humongous)和复制回收算法(survivor)。
GC模式
Young GC(回收Eden、Survivor区):选定所有年轻代的Region,通过控制年轻代个数,来控制young GC 的时间开销(复制回收算法)
Mixed GC(全部区域回收):不但选定年轻代Region还要选定老年代收益高的若干Region,进行释放。Mixed GC 不是Full GC,如果Mixed GC 跟不上程序分配内存速度,就会使用serial odl GC(Full GC)来收集整个GC heap。4G1不是Full GC。
全局并发标记
1, 初始标记:仅仅标记一下GC Roots能直接关联的对象,此阶段需要停顿线程(STW),但耗时很短。
2, 并发标记:从GC Roots开始对堆进行可达性分析,找到活对象,耗时很长,但与用户程序并行
3,最终标记:为了修正并发标记阶段因用户程序继续而导致标记产生变动的那一部分标记记录。需要停顿线程(STW),但是可并行执行。
4,筛选回收:首先对各个Region中的回收价值和成本进行排序,根据用户所期望的GC停顿时间来指定回收计划。此阶段与用户并行一起并行执行,但是因为回收一部分Region,时间是用户可控的,而且停顿用户线程能大幅度提交收集效率。
特点
1, 空间整理:不会产生内存碎片。算法为标记-整理和复制回收算法。
2, 可预测的停顿:G1,刷选不是经常使用,而是刷选那些回收效率比较高的区域(回收回报比比较高)。总共1000个区域,一个区域10m * 筛选常用的100个区域 急需回收。
Stop The World
GC收集器和GC优化的目标就是尽可能的减少STW的时间和次数。