java虚拟机(四)--垃圾回收算法与垃圾收集器

本文深入解析了各种垃圾回收算法的特点及应用场景,包括标记-清除、复制、标记-整理算法,并介绍了HotSpot虚拟机中的实现细节。同时,还对比了多种垃圾收集器如Serial、ParNew、Parallel Scavenge、CMS、G1等的工作原理及其配置参数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

“标记-清除”算法:

先标记出所有存活的对象,标记完成后,回收没有标记的空间。
缺点:效率低,空间碎片(导致GC次数增多)

“复制”算法:

将内存分成2块,一块满了的时候,将存活的对象复制到另外一块上面,然后把这块完整清除。
现在商业虚拟机一般采用这种算法,将内存分为一个新生代和两个幸存代,比例为8:1(默认),触发GC时,将新生代和一个幸存代中的存活对象复制到另一个幸存代中,只有10%内存被浪费(另一个幸存代不够用时,会存到老年代)。

“标记-整理”算法

对象存活率较高时,复制算法成本高。所以老年代一般采用“标记-整理”算法,先标记所有存活对象,然后把所有对象向一端移动,直接清理掉端边界以外的内存。

hotspot虚拟机中:
可达性分析,采用枚举根节点的方式,可以作为节点的点主要在全局性引用,执行上下文之中。

在类加载完成后,虚拟机会把对象内什么偏移量上是什么类型的数据记录下来,JIT编译时,也会记录栈和寄存器中哪些位置是引用。这样GC就可以快速检查所有引用。

hotspot在安全点(指令复用前,一般是循环,方法调用,异常抛出)创建OopMap。安全点的是当前线程可能挂起的点,给GC让位。

需要暂停线程时,虚拟机把安全点处的内存页置为不可读,发生异常,由预先注册的异常处理器暂停线程,实现等待。

安全域是针对那些休眠和阻塞的线程的,那些线程在离开安全域时会检查根节点是否枚举完成,没有完成则等待。

新生代一般采用复制算法,老年代一般使用标记-整理算法

Serial收集器:

是client模式下的虚拟机 新生代的默认收集器。简单高效,缺点是会暂停用户线程。

ParNew收集器:

parnew是serial收集器的多线程版本,是server模式的虚拟机首选的新生代收集器,另一个重要原因是它能与CMS收集器配合使用
可以使用-XX:+UseParNewGC选项来强制指定使用它
使用-XX:ParallelGCThreads来限制垃圾收集的线程数

Parallel Scavenge收集器:

它的特点是关注点与众不同,它的目标是达到一个可控的吞吐量,-XX:MaxGCPauseMills设置每次GC的时间,设的小的话,新生代也会变小,gc次数会增多。
-XX:GCTimeRadio直接设置吞吐量的倒数,默认值为99.
把-XX:MaxGCPauseMillis参数的最大值以及-Xmx最大值设置好,然后使用GC自适应调节策略,是一种虚拟机优化的不错的选择。

***Serial Old***是Serial收集器的老年代版本,一般在Client模式下启动,可以与Parallel Scavenge收集器使用,也可以与CMS配合在Concurrent Mode Failure时使用。

***Parallel Old***是Parallel Scavenge收集器的老年代版本(1.6之后才存在),配合 Parallel Scavenge使用

CMS收集器:

它是一种以获取最短回收停顿时间为目的的收集器。提升服务响应速度,用于B/S系统服务端。
使用标记-清除算法

  1. 初始标记
  2. 并发标记
  3. 重新标记
  4. 并发清除

初始标记只标记GC Roots能直接关联到的对象,速度快(此期间用户线程暂停)。
并发标记是从Tracing进行栈追踪,完成所有对象的标记。
重新标记则修正并发标记期间因用户程序继续执行而产生变动的那一部分对象的标记记录。(用户线程暂停)。
并发清除则清除所有标记的对象。

缺点:并发标记和并发清除时,抢占了CPU资源,导致吞吐量降低,应用程序变慢。 而且有标记-清除的缺点(-XX:+UseCMSCompactAtFullCollection参数,在Full GC前合并整理内存碎片,-XX:CMSFullGCsBeforeCompaction用来指定执行多少次Full GC时执行碎片整理,默认0,表示每次都执行),无法处理浮动垃圾,出现Concurrent Mode Failure失败导致Full GC。在并发清除以及标记期间用户程序产生的新垃圾也无法在本次GC时回收,所以老年代需要预留部分空间。

出现Concurrent Mode Failure 失败后会启动后备预案,使用Serial Old回收老年代

G1收集器是收集器技术发展的前沿成果,在jdk1.7后开始使用,不用与其他垃圾回收期配合。
特点:

并行与并发:缩短STW的时间,在GC同时,让用户程序继续执行。
分代收集
空间整合:整体基于 “标记-整理”算法,在局部2代之间使用“复制”算法。减少GC触发的次数
可预测的停顿:可以指定在长度M的时间内,垃圾回收时间不超过N

G1收集器将整个java堆分为多个相等的独立区域(Region),每个Region有它的回收价值(垃圾所占用空间/垃圾回收花费的时间),优先回收价值最大的Region,保证竟可能高的收集效率。

如何判断一个Region中的某个对象是否存活?
每个region都有一个Remembered Set,虚拟机发现有程序进行Reference对象的写操作时,会检查所引用的对象是否在同一个Region中,如果不在,那么被引用的对象所在Region对应的Remembered Set就会记录相关信息。
内存回收时,从根节点枚举Remembered set保证不对全堆扫描。

初始标记:只扫描从GC ROOTS直接关联到的对象(STW)
再次标记:并发执行,从根节点出发寻找不可达的对象标记
最终标记:确认上一步标记的对象的状态(STW)
清理标记。(并发)

分代算法将堆区划分为新生代和老年代,分区算法将整个堆空间划分为很多个小空间,每次回收部分空间。


常用命令:
在这里插入图片描述-Xmn指定新生代的大小
-XX:NewRatio=3 老年代和新生代的比例。
-Xss 指定线程栈的大小

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值