首页 > 其他分享 >JVM垃圾回收(二)

JVM垃圾回收(二)

时间:2022-12-14 21:11:58浏览次数:67  
标签:新生代 回收 XX GC 垃圾 JVM 串行

参考资料:
https://shuyi.tech/archives/jvm-serial-09-jvm-garabage-collector

Java 虚拟机的垃圾回收器可以分为四大类别:串行回收器、并行回收器、CMS 回收器、G1 回收器。
如果按使用内存区域不同可以分为:

  • 年轻代回收器:新生代串行回收器(Serial)、新生代ParNew回收器(并行回收器)、新生代Parallel GC回收器(并行回收器)
  • 老年代回收器:老年代串行回收器(Serial Old)、Parallel Old(并行回收器)、 CMS
  • 对整个堆内存:G1

串行回收器

串行回收器是指使用单线程进行垃圾回收的回收器。因为每次回收时只有一个线程,因此串行回收器在并发能力较弱的计算机上,其专注性和独占性的特点往往能让其有更好的性能表现。

串行回收器可以在新生代和老年代使用,根据作用于不同的堆空间,分为新生代串行回收器和老年代串行回收器。

新生代串行回收器

新生代串行回收器使用的是复制算法。在串行回收器进行垃圾回收时,会触发 Stop-The-World 现象,即其他线程都需要暂停,等待垃圾回收完成。

使用 -XX:+UseSerialGC 参数可以指定使用新生代串行收集器和老年代串行收集器。当虚拟机在 Client 模式下运行时,其默认使用该垃圾收集器。

老年代串行回收器

老年代串行回收器中使用的是标记压缩算法。其与新生代串行收集器一样,只能串行、独占式地进行垃圾回收,因此也经常会有较长时间的 Stop-The-World 发生。

但老年代串行回收器的好处之一,就是其可以与多种新生代回收器配合使用。若要启用老年代串行回收器,可以尝试以下参数:

-XX:UseSerialGC:新生代、老年代都使用串行回收器。
-XX:UseParNewGC:新生代使用 ParNew 回收器,老年代使用串行回收器。
-XX:UseParallelGC:新生代使用 ParallelGC 回收器,老年代使用串行回收器。

并行回收器

并行回收器在串行回收器的基础上做了改进,其使用多线程进行垃圾回收。对于并行能力强的机器,可以有效缩短垃圾回收所使用的时间。
根据作用内存区域的不同,并行回收器也有三个不同的回收器:新生代 ParNew 回收器、新生代 ParallelGC 回收器、老年代 ParallelGC 回收器。


新生代 ParNew 回收器

其只是简单地将串行回收器多线程化,其回收策略、算法以及参数和新生代串行回收器一样。

新生代 ParNew 回收器同样使用复制的垃圾回收算法,其垃圾收集过程中同样会触发 Stop-The-World 现象。但因为其使用多线程进行垃圾回收,因此在并发能力强的 CPU 上,其产生的停顿时间要短于串行回收器。
要开启新生代 ParNew 回收器,可以使用以下参数:

-XX:+UseParNewGC:新生代使用 ParNew 回收器,老年代使用串行回收器。
-XX:UseConcMarkSweepGC:新生代使用 ParNew 回收器,老年代使用 CMS。
-XX:ParallelGCThreads:指定 ParNew 回收器的工作线程数量。

新生代 Parallel GC 回收器

新生代 Parallel GC 回收器与新生代 ParNew 回收器非常类似,其也是使用复制算法,都是多线程、独占式的收集器,也会导致 Stop-The-World。但和 ParNew 回收器的一个重大不同是:其非常注重系统的吞吐量。

之所以说新生代 Parallel GC 回收器非常注重系统吞吐量,是因为其有一个自适应 GC 调节策略。我们可以使用 -XX:+UseAdaptiveSizePolicy 参数打开这个策略,在这个模式下,新生代的大小、Eden 和 Survivor 的比例、晋升老年代的对象年龄等参数都会被自动调节,已达到堆大小、吞吐量、停顿时间的平衡点。

Parallel GC 回收器提供了两个重要参数用于控制系统的吞吐量。

-XX:MaxGCPauseMillis:设置最大垃圾收集停顿时间。在 ParallelGC 工作时,其会自动调整响应参数,将停顿时间控制在设置范围内。为了达到目的,其可能会使用较小的堆,但这会导致 GC 较为频繁。
-XX:GCTimeRatio:设置吞吐量大小,其实一个 0 - 100 的整数。假设 GCTimeRatio 的值为 n,那么系统将不花费超过 1/(1+n) 的时间用于垃圾手机。比如 GCTimeRatio 值为 19,那么系统用于垃圾收集的时间不超过 1 /(1+19) = 5%。默认情况下,它的取值是 99,即不超过 1% 的时间用于垃圾收集。

新生代 Parallel GC 回收器可以使用以下参数启用:

-XX:+UseParallelGC:新生代使用 Parallel 回收器,老年代使用串行回收器。
-XX:+UseParallelOldGC:新生代使用 ParallelGC 回收器,老年代使用 ParallelOldGC 回收器。

老年代 ParallelOldGC 回收器

老年代 ParallelOldGC 回收器也是一种多线程并发的回收器,与新生代 ParallelGC 收集器一样,其也是注重吞吐量的收集器,只不过其是作用于老年代。

ParallelOldGC 回收器使用的是标记压缩算法,只有在 JDK 1.6 中才可以使用。我们可以使用-XX:UseParallelOldGC参数在新生代中使用 ParallelGC 收集器,在老年代中使用 ParallelOldGC 收集器。参数 -XX:ParallelGCThreads也可以用于设置垃圾回收时的线程数量。

CMS 回收器

与 ParallelGC 和 ParallelOldGC 不同,CMS 回收器主要关注系统停顿时间。CMS 回收器是一个使用多线程并行回收的垃圾回收器。

工作步骤

CMS 的主要工作步骤有:初始标记、并发标记、预清理、重新标记、并发清除和并发充值。其中初始标记和重新标记是独占系统资源的,而其他阶段则可以和用户线程一起执行。

在整个 CMS 回收过程中,默认情况下会有预清理的操作,我们可以关闭开关 -XX:-CMSPrecleaningEnabled 不进行预清理。因为重新标记是独占 CPU 的,因此如果新生代 GC 发生之后,立刻出发一次新生代 GC,那么停顿时间就会很长。为了避免这种情况,预处理时会刻意等待一次新生代 GC 的发生,之后在进行预处理。

主要参数

启动 CMS 回收器刻意使用参数:-XX:+UseConcMarkSweepGC,线程并发数量刻意通过 -XX:ConcGCThreads 或 -XX:ParallelCMSThreads 参数设定。

此外,我们还可以设置 -XX:CMSInitiatingOccupancyFraction 来指定老年代空间使用阈值。当老年代空间使用率达到这个阈值时,会执行一次 CMS 回收,而不像其他回收器一样等到内存不够用的时候才进行 GC。

标记清除算法的缺点是会产生内存碎片,因此 CMS 回收器会产生较多内存碎片。我们可以使用 XX:+UseCMSCompactAtFullCollection 参数让 CMS 在完成垃圾回收后,进行一次内存碎片整理。使用 -XX:CMSFullGCsBeforeCompaction 参数设置进行多少次 CMS 回收后,进行一次内存压缩。

此外,如果希望使用 CMS 回收 Perm 区,那么则可以打开 -XX:+CMSClassUnloadingEnabled 开关。打开该开关后,如果条件允许,那么系统会使用 CMS 的机制回收 Perm 区 Class 数据。

G1 回收器

G1 回收器拥有独特的垃圾回收策略,和之前所有垃圾回收器采用的垃圾回收策略不同。从分代看,G1 依然属于分代垃圾回收器。但它最大的改变是使用了分区算法,从而使得 Eden 区、From 区、Survivor 区和老年代等各块内存不必连续。

在 G1 回收器之前,所有的垃圾回收器其内存分配都是连续的一块内存,如下图所示。

image

而在 G1 回收器中,其将一大块的内存分为许多细小的区块,从而不要求内存是连续的。
image

工作步骤

G1 收集器的收集过程主要有四个阶段:

新生代 GC
并发标记周期
混合收集
如果需要,可能进行 FullGC

新生代 GC 与其他垃圾收集器的类似,就是清空 Eden 区,将存活对象移动到 Survivor 区,部分年龄到了就移动到老年代。

并发标记周期则分为:初始标记、根区域扫描、并发标记、重新标记、独占清理、并发清理阶段。其中初始标记、重新标记、独占清理是独占式的,会引起停顿。并且初始标记会引发一次新生代 GC。在这个阶段,所有将要被回收的区域会被 G1 记录在一个称之为 Collection Set 的集合中。

混合回收阶段会首先针对 Collection Set 中的内存进行回收,因为这些垃圾比例较高。G1 回收器的名字 Garbage First 就是这个意思,垃圾优先处理的意思。在混合回收的时候,也会执行多次新生代 GC 和 混合 GC,从而来进行内存的回收。

必要时进行 Full GC。当在回收阶段遇到内存不足时,G1 会停止垃圾回收并进行一次 Full GC,从而腾出更多空间进行垃圾回收。

相关参数

打开 G1 收集器,我们可以使用参数:`-XX:+UseG1GC。

设置目标最大停顿时间,可以使用参数:-XX:MaxGCPauseMillis。

设置 GC 工作线程数量,可以使用参数:-XX:ParallelGCThreads。

设置堆使用率触发并发标记周期的执行,可以使用参数:-XX:InitiatingHeapOccupancyPercent。

标签:新生代,回收,XX,GC,垃圾,JVM,串行
From: https://www.cnblogs.com/d111991/p/16983547.html

相关文章

  • php垃圾回收机制(PHP新的垃圾回收机制:Zend GC详解)
    概述    在5.2及更早版本的PHP中,没有专门的垃圾回收器GC(GarbageCollection),引擎在判断一个变量空间是否能够被释放的时候是依据这个变量的zval的refcount的值,如果refcou......
  • centos7清理docker垃圾文件
    相信很多朋友都有这个docker容器导致主机磁盘空间满了的问题,应用容器在宿主机上长期运行,应用实例启停容器,会产生大量的停止的容器,无容器使用的数据卷、网络配置,无容器......
  • JVM垃圾回收(一)
    参考资料:https://shuyi.tech/archives/jvm-serial-08-jvm-garbage-collectionhttps://zhuanlan.zhihu.com/p/112018694判断哪些是垃圾现今Java虚拟机判断垃圾对象使......
  • Java性能调优System的gc垃圾回收方法
    java性能调优System的gc垃圾回收方法java性能调优System的gc垃圾回收方法示例解一、什么是System.gc()?​​System.gc()​​是用Java,C#和许多其他流行的高级编程语言提供的API......
  • 知识回顾-JDK有哪些垃圾收集器及收集器组合
    目录经典垃圾收集器新生代Serial收集器ParNew收集器ParallelScavenge收集器老年代SerialOld收集器ParallelOld收集器CMS收集器G1收集器ZGC收集器如何获取使用的默认的垃......
  • 【JVM】Java 通过 javap 命令分析java汇编指令
      javap是jdk自带的反解析工具。它的作用就是根据class字节码文件,反解析出当前类对应的code区(汇编指令)、本地变量表、异常表和代码行偏移量映射表、常量池等等信息。当然......
  • 【JVM】VisualVM Java程序性能分析工具
     【JVM】VisualVMJava程序性能分析工具 介绍VisualVM是一个集成多个JDK命令行工具的可视化工具。可以作为Java应用程序性能分析和运行监控的工具。开发人员可以利用它来......
  • KingbaseES垃圾回收参数优化之maintenance_work_mem
    maintenance_work_mem参数说明与vacuum过程maintenance_work_mem,autovacuum_work_mem。如果没有设置autovacuum_work_mem,默认值是-1,则使用maintenance_work_mem的设......
  • 解读JVM级别本地缓存Caffeine青出于蓝的要诀2 —— 弄清楚Caffeine的同步、异步回源方
    大家好,又见面了。本文是笔者作为掘金技术社区签约作者的身份输出的缓存专栏系列内容,将会通过系列专题,讲清楚缓存的方方面面。如果感兴趣,欢迎关注以获取后续更新。上......
  • JVM类的加载机制
    1类的加载机制的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个java.lang.Class对象,用来封装类在方法区内的......