二者的本质差异在于标记-清除算法是一种非移动式的回收算法,标记-整理是移动式的。是否移动回收后的存活对象是一项优缺点并存的风险决策。可以看到,标记的存活对象会被整理,按照内存地址依次排列,而未标记的内存会被清理掉。如此一来,当我们需要给新对象分配内存时,JVM只需要持有一个内存的起始地址即可,这比维护一个空闲列表显然少了许多开销。
标记-整理的优缺点
优点
消除了标记-清除算法当中,内存区域分散的缺点,没有碎片的问题,我们需要给新对象分配内存时,JVM只需要持有一个内存的起始地址即可。
消除了复制算法当中,内存减半的高额代价。
缺点
从效率上来说,标记-整理算法要低于复制算法
移动对象的同时,如果对象被其他对象引用,则还需要调整引用的地址
移动过程中,需要全程暂停用户应用程序。即:STW
小结效率上来说,复制算法是当之无愧的老大,但是却浪费了太多内存。
而综合来看,标记-整理算法相对来说更好一些,但是效率上不尽如人意,它比复制算法多了一个标记的阶段,比标记-清除多了一个整理内存的阶段。
标记清除 标记整理 复制速率 中等 最慢 最快
空间开销 少(但会堆积碎片) 少(不堆积碎片) 通常需要活对象的2倍空间(不堆积碎片)
移动对象 否 是 是
ps:没有最好的算法,只有最合适的算法
垃圾回收器垃圾收集器分类
按线程数分:串行垃圾回收器和并行垃圾回收器串行回收指的是在同一时间段内只允许有一个CPU用于执行垃圾回收操作,此时工作线程被暂停,直至垃圾收集工作结束。
在诸如单CPU或者较小的应用内存等硬件平台不是特别优越的场合,串行回收器的性能表现可以超过并行回收器和并发回收器。所以,串行回收默认被应用在客户端的Client模式下的JVM中。
在并发能力比较强的CPU上,并行回收器产生的停顿时间要短于串行回收器。
和串行相反,并行收集可以运用多个CPU同时执行垃圾回收,因此提升了应用的吞吐量,不过并行回收仍然与串行回收一样,采用独占式,使用了“stop-the-world”机制。
按工作模式分:并发式垃圾回收器和独占式垃圾回收器并发式垃圾回收器与应用程序线程交替工作,以尽可能减少应用程序的停顿时间。
独占式垃圾回收器一旦运行,就停止应用程序中的所有用户线程,直到垃圾回收过程完全结束。
压缩式垃圾回收器会在回收完成后,对存活对象进行压缩整理,消除回收后的碎片
非压缩式的垃圾回收器不进行这步操作
按工作的内存空间分:年轻代垃圾回收器和老年代垃圾回收器不同的垃圾回收器概述
垃圾收集机制是Java的招牌能力,极大地提高了开发效率。
那么,Java常见的垃圾收集器有哪些?
垃圾回收器发展史有了虚拟机,就一定需要收集垃圾的机制,这就是Garbage Collection,对应的产品我们称为Garbage Collector。
1999年随JDK1.3.1一起来的是串行方式的serialGC,它是第一款GC。ParNew垃圾收集器是Serial收集器的多线程版本
2002年2月26日,Parallel GC和Concurrent Mark Sweep GC跟随JDK1.4.2一起发布·
Parallel GC在JDK6之后成为HotSpot默认GC。
2012年,在JDK1.7u4版本中,G1可用。
2017年,JDK9中G1变成默认的垃圾收集器,以替代CMS。
2018年3月,JDK10中G1垃圾回收器的并行完整垃圾回收,实现并行性来改善最坏情况下的延迟。
2018年9月,JDK11发布。引入Epsilon 垃圾回收器,又被称为 "No-Op(无操作)“ 回收器。同时,引入ZGC:可伸缩的低延迟垃圾回收器(Experimental)
2019年3月,JDK12发布。增强G1,自动返回未用堆内存给操作系统。同时,引入Shenandoah GC:低停顿时间的GC(Experimental)。
2019年9月,JDK13发布。增强ZGC,自动返回未用堆内存给操作系统。
2020年3月,JDK14发布。删除CMS垃圾回收器。扩展ZGC在mac os和Windows上的应用
7种经典的垃圾收集器串行回收器:Serial、Serial Old
并行回收器:ParNew、Parallel Scavenge、Parallel Old