HotSpot中的垃圾收集器

垃圾收集器就是GC算法的落地实现!

  • 如何查看服务器默认的垃圾收集器?
	java -XX:+PrintCommandLineFlags -version

在这里插入图片描述


在这里插入图片描述


新生代垃圾收集器


串行收集器Serial

一个单线程的收集器,在进行垃圾收集的时候,必须暂停其他所有的工作线程(Stop-The-World)直到他的垃圾收集结束
在这里插入图片描述
最古老,最稳定,效率最高

缺点:只使用一个线程去回收但其在进行垃圾收集过程中可能会产生较长的停顿(Stop-the-world状态

优点:简单高效

对于限定单个CPU环境来说,没有线程交互的开销可以获得最高的单线程垃圾收集效率,因此Serial垃圾收集器依然是java虚拟机运行在Client模式下默认的新生代垃圾收集器

对应的JVM参数是:-XX:+UserSerialGC

开启后会使用:==Serial(新生代)+Serial Old(老年代)==的垃圾收集器组合

表示:新生代和老年代都会使用串行垃圾回收器,新生代使用复制算法老年代使用标记-整理算法


并行收集器ParNew

使用多线程进行垃圾回收,在垃圾收集时,会Stop-the-World暂停其他所有的工作线程直到他收集结束。
在这里插入图片描述
PerNew其实就是Serial收集器新生代的并行多线程版本,最常见的应用场合就是配合老年代的CMS工作,其余的行为和Serial收集器完全一样,ParNew垃圾收集器在垃圾收集过程同样也要暂停所有其他的工作线程。他是很多java虚拟机运行在Server模式下的新生代的默认垃圾收集器

对应参数:-XX:+UserParNewGC,启用ParNew收集器,只影响新生代,不影响老年代

会使用ParNew(young区)+Serial Old垃圾回收器组合新生代使用复制算法老年代使用标记-整理算法

Java HotSpot™ 64-Bit Server VM warning: Using the ParNew young collector with the Serial old collector is deprecated and will likely be removed in a future release 该组合以及被淘汰了


并行收集器Parallel Scavenge

在这里插入图片描述
Parallel Scavenge垃圾回收器类似于ParNew也是一个新生代垃圾收集器,也使用复制算法,也是一个并行的多线程的垃圾收集器,俗称吞吐量优先收集器。一句话:串行收集器在新生代和老年代的并行化

他重点关注的是:

​ ==可控的吞吐量(Thoughtput = 运行用户代码时间/(运行用户代码时间+垃圾收集时间)),也就是程序运行100分钟,垃圾收集1分钟,吞吐量=99%.==高吞吐量意味着高效利用CPU的时间,他多用于后台运算而不需要太多交互的任务

自使用调节策略也是Parallel Scavenge垃圾回收器与ParNew收集器的一个重要区别。(自适应调节策略:虚拟机会根据当前系统的运行情况收集性能监控信息,动态调整这些参数以提供最合适的停顿时间(-XX:MaxGCPauseMillis)或最大的吞吐量)

参数:-XX:+UseParallelGC或者-XX:UserParallelOldGC(可以互相激活)

开启后,新生代使用复制算法,老年代使用标记整理算法


老年代垃圾收集器


并行收集器ParallelOld

ParallelOld收集器是Parallel垃圾收集器的老年代版本,使用多线程的标记-整理算法,ParallelOld收集器在JDK1.6才开始提供。

JDK1.8之后,使用(Parallel Scaveng+Parallel Old)

参数:-XX:+UserParallelOldGC,使用之后,新生代Parallel,老年代Parallel Old


并发标记清除垃圾收集器CMS

在这里插入图片描述
CMS 并发标记清除并发收集低及停顿,并发指的是与用户线程一起执行,基于“ 标记-清除”算法实现。整个过程分为四个步骤:

  1. 初始标记(伴随STW)
  2. 并发标记
  3. 重新标记(伴随STW)
  4. 并发清除

适合应用在互联网站或者B/S系统的服务器上,这类应用尤其重视服务器的响应速度,希望系统停顿时间最短

CMS也适合堆内存大,CPU核数多的服务器端应用,也是G1出现之前大型应用的首选收集器。

参数:-XX:+UseConcMarkSweepGC , 开启之后自动打开-XX:+UseParNewGC

开启参数后,使用ParNew(Young区)+CMS(Old区)+Serial Old的收集器组合Serial Old将作为CMS出错的后备收集器

优点:并发收集低停顿

缺点:

  • CPU资源压力大

    由于并发进行,CMS在收集与应用线程会同时增加对堆内存的占用,也就是说,CMS必须要在老年代堆内存用尽之前完成垃圾回收,否则CMS回收失败时,触发担保机制(使用Serial Old收集器),串行老年代收集器将会以STW的方式进行一次GC,从而造成较大停顿时间

  • 采用的标记清除算法会导致大量碎片

    标记清除算法无法整理空间碎片,老年代空间会随着应用时长被逐步耗尽,最后将不得不不通过担保机制对堆内存进行压缩。CMS也提供了参数-XX:CMSFullGCsBeForeCompaction(默认0,即每次都进行内存整理)来制定多少次CMS收集之后,进行一次压缩的FUll GC


G1垃圾收集器(Garbage First)

G1收集器,是一款面向服务端应用的收集器,与其他垃圾收集器不同的是,G1垃圾收集器只有元空间和G1 区,G1横跨年轻代和老年代。应用在多处理和大容量内存环境中,在实现高吞吐量的同时,尽可能的满足垃圾收集暂停时间的要求。另外还具有以下特性:

  • 像CMS收集器一样,能与应用程序线程并发执行
  • 整理空闲时间更快
  • 需要更多的时间来预测GC停顿时间
  • 不希望牺牲大量的吞吐性能
  • 不需要更大的JavaHeap

G1收集器的设计目标是取代CMS收集器,他比CMS更出色:

  • G1是一个有整个内存过程的垃圾收集器,不会产生内存碎片
  • G1的STW更可控,G1在停顿时间上添加了预测机制,用户可以指定期望停顿时间

G1的特点:

  • G1 能充分利用多 CPU、多核环境硬件优势,尽量缩短 STW。
  • G1 整体采用标记-整理算法,局部是通过是通过复制算法不会产生内存碎片
  • 宏观上看 G1 之中不再区分年轻代和老年代,被内存划分为多个独立的子区域。
  • G1 收集器里面讲整个的内存区域混合在一起,但其本身依然在小范围内要进行年轻代和老年代的区分。保留了新生代和老年代,但她们不在是物理隔离,而是一部分 Region 的集合且不需要 Region 是连续的,也就是说依然会采用不同的 GC 方式来处理不同的区域。
  • G1 虽然也是分代收集器,但整个内存分区不存在物理上的年轻代和老年代的区别,也不需要完全独立的 Survivor to space 堆做复制准备。G1 只有逻辑上的分代概念,或者说每个分区都可能随 G1 的运行在不同代之间前后切换。

G1的底层原理在这里插入图片描述
在这里插入图片描述

  • Region 区域化垃圾收集器:最大好处是化整为零,避免全内存扫描,只需要按照区域来进行扫描即可。
  • 回收过程:
    • 针对Eden区进行收集,Eden区耗尽后会被触发,主要是小区域收集+形参连续的内存块,避免内存碎片
      • Eden区的数据移动到Survivor区,假如出现Survivor区空间不够,Eden区数据会晋升到Old区
      • Survivor区的数据移动到新的Survivor区,部分数据会晋升到Old区
      • 最后,Eden区收拾干净了,GC结束,用户的应用程序继续执行
  • 四步过程:
    • 初始标记:标记一下GC Roots能直接关联到的对象,需要停顿线程,但耗时很短
    • 并发标记:是从GC Root开始对堆中对象进行可达性分析,找出存活的对象,这阶段耗时较长,但可与用户程序并发执行
    • 最终标记:修正在并发标记期间因用户程序继续运作而导致标记产生变动的那一部分标记记录
    • 筛选回收:对各个Region的回收价值和成本进行排序,根据用户所期望的GC停顿时间来制定回收计划

配置参数:

  • -XX:UseG1GC

  • -XX:G1HeapRegionSize=n:设置G1区域的大小,值是2的幂

  • -XX:MaxGCPauseMillis=n:设置并行收集最大暂停时间

各种经典垃圾收集器之间的搭配组合关系如下图:
在这里插入图片描述

垃圾收集器的配置参数

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值