JVM常见的垃圾收集器

1. Serial Colletor: -xx:+UseSerialGC.

它是一个单线程的,比较适合单核cpu的场景。

适用的场景:cpu核数比较少、内存空间比较少 100MB

新老年代之分:适用于新生代、老年代。灰色代表垃圾收集线程会暂停业务代码线程。后果就是对于客户端而言,响应变慢了。

现在所用的所有jvm垃圾收集,都有stop the world ,只是时间长短不一样。

为什么会停止业务代码的线程呢,就是希望业务代码不要执行,如果执行就会产生两个问题:

  1. 如果进行GC时,垃圾对象都会有一个标记,这个时候业务线程没有停下,业务线程可能会用到这个标记的垃圾对象,但这个对象是需要清理的。
  2. 归根到底,因为堆中的对象可能会发生变化(eden转移到servivor),不能让业务代码一直使用,如果一直使用,都是使用到旧地址。

2. Parallal GC XX:+UseParallelGC

既然单线程比较慢,那么就可以采用多线程(吞吐量优先),也有stw ,多线程收集、也有适用于新老年代的收集器。

3. Concurrent Mark Sweep(CMS) Collector

特点:更短的暂停响应时间,命令 -XX:UseConcMarkSweepGC。但需要注意的一点是,这个处理器只适合老年代。适用的是标记-清理算法,所以会有空间碎片的问题。

4. G-First

也是尽可能满足用户设置的停顿时间目标,并且很好解决了空间碎片问题。命令 -XX:UseG1GC.

吞吐量也会比较高。适用于新老年代。

5. ZGC(-XX:UseZGC)

可以是停顿时间达到几毫秒,但牺牲了一些吞吐量。

4. 垃圾收集器的分类

  1. 串行:只有一个垃圾收集线程执行 Serial
  2. 并行:有多个垃圾收集线程执行,业务代码不执行 Parallel GC 更加关注吞吐量
  3. 并发:垃圾收集线程和业务线程会同时执行 CMS G1 ZGC 更加关注停顿时间

吞吐量和停顿时间是评判一个垃圾收集器好坏的两个重要指标。

5. CMS

CMS是追求停顿时间的,目标域是老年代,也是一款老年代收集器,它会尝试最小化停顿时间,不会进行拷贝或压缩我们的对象,就意味着有空间碎片的问题。

如果你使用了CMS,那么新生代则会搭配一个ParNew。

通常情况下,一个新生代搭配一个老年代。当然如果这个GC可以用于老年代,也可以不用搭配。

采集器的四个阶段:

第一个阶段:初始标记

它会标记哪些可达的对象

第二个阶段并发标记:

第三阶段重新标记:

这三个标记都是为了确保对象的可达性

有一些阶段:垃圾收集线程和业务代码线程是共同执行的,所以停顿时间相对就少了。

针对CMS的不足,需要的解决方案:

  1. 停顿时间能不能再低一点
  2. 空间能否连续

针对这两种情况,于是有了G-First收集器

6. G1

满足低停顿的目标,又不会太牺牲吞吐量。停顿时间可以缩短到200ms以内、

还解决了空间碎片问题,从两个角度:
第一个,就是老年代算法,标记-整理

第二个,就是内存划分 region的概念

这个是C1的回收过程:

G1是将内存空间分成一个大小相同的regions,每一个都是连续的虚拟内存。这里的内存其实是对物理内存的映射。原先的堆内存空间是连续的,从young到old是按顺序的。而在G1中,也有完整的内存空间,但是新老年代不是连续的,不需要像以前一样在物理上连续,只需要在逻辑上连续。

前提:这些region的角色是可以转换的。

region的大小固定:区间:2^0 M- 2^5M 1-32M

如果超过region的50%称为大对象。

6.1. youngGC

youngGC前堆内存的状态

进行GC后,和前面的GC流程一样,会进入到survivor区,年龄大的会进入old区。在这个过程中依然会进入stop the world。

完成之后就变成这样:

小结:

  1. 这些region是物理上不连续的
  2. 当进行youngGC时,会进入stop the world
  3. 存活的对象会放到survivor、老年代
6.2. oldGC

也会有初始标记、并发标记、筛选回收这些步骤

其中初始标记、并发标记、最终标记、筛选标记都是扫描操作,找出不可达对象作为垃圾对象,并且开始清理,清理完成后,还有一个copy操作,主要为了下次进行。

Carvage-First

垃圾优先:这些对象region中有存活的对象,也有垃圾对象,那意思就是在回收的时候会有一个优先级。如何选择优先级呢:

先回收垃圾对象最多的region,因为存活率很少,就先回收。

回收这些region可以释放更多的空间,存活对象也比较少,说明可以更加快速、轻松的整理这些对象。

并且不是一个实时回收期,可以设置停顿时间,并且可以选择性回收。

垃圾回收的时机

  1. Sytem.gc
  2. Eden 空间不够用了
  3. old 空间不够用了
  4. MetaSapce 不够用了

Young GC = Minor GC

Old GC = Mahior GC

Full GC =Young + Old +Metaspace

Full GC =Young + Old

在虚拟机中一定要避免GC,这是第一个维度,优先级最高的

即使要发生GC,也尽可能发生在young区

如果避免不了发生major gc ,那jvm内部会有一个算法:每一次major之前,会先触发一次young gc

当发生old gc ,其实就等同发生full gc

  • 25
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
JVM (Java Virtual Machine) G1 (Garbage-First) 垃圾收集器是一种用于 Java 应用程序的垃圾收集算法。它是自JDK 7u4版本后引入的一种全新的垃圾收集器。 G1垃圾收集器的设计目标是为了解决传统的分代垃圾收集器可能遇到的一些问题,如停顿时间长、内存碎片化等。它采用了一种基于区域的垃圾收集方式,可以将内存划分为多个大小相等的区域,每个区域可以是Eden、Survivor或Old区。 G1垃圾收集器的工作原理如下: 1. 初始标记(Initial Mark):标记所有从根对象直接可达的对象。 2. 并发标记(Concurrent Mark):在并发执行程序的同时,标记那些在初始标记阶段无法访问到的对象。 3. 最终标记(Final Mark):为并发标记阶段中发生改变的对象进行最终标记。 4. 筛选回收(Live Data Counting and Evacuation):根据各个区域的回收价值来优先回收价值低的区域。 G1垃圾收集器具有以下特点: - 并发执行:在执行垃圾收集过程时,尽可能减少应用程序的停顿时间。 - 分区回收:将整个堆划分为多个区域,可以根据需要优先回收垃圾较多的区域,从而避免全堆回收带来的长时间停顿。 - 内存整理:G1垃圾收集器会对内存进行整理,减少内存碎片化,提高内存利用率。 需要注意的是,G1垃圾收集器并不适用于所有情况。在特定的场景下,如大堆情况下的长时间运行、对延迟要求非常高的应用等,可能需要考虑其他垃圾收集器的使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值