【Java】图解 JVM 垃圾回收(二):垃圾收集器、Full GC

news2025/1/17 21:44:39

图解 JVM 垃圾回收(二)

  • 1.垃圾收集器
    • 1.1 内存分配与回收策略
    • 1.2 Serial 收集器
    • 1.3 Parallel Scavenge 收集器
    • 1.4 ParNew 收集器
    • 1.5 CMS 收集器
    • 1.6 G1 收集器
  • 2.Full GC 的触发条件

1.垃圾收集器

Java 虚拟机提供了多种垃圾回收器,每种回收器有其特定的用途和优势。以下是常见的垃圾回收器:

在这里插入图片描述
连线表示垃圾收集器可以配合使用。

  • 单线程与多线程:单线程指的是垃圾收集器只使用一个线程进行收集,而多线程使用多个线程。
  • 串行与并行:串行指的是垃圾收集器与用户程序交替执行,这意味着在执行垃圾收集的时候需要停顿用户程序;并行指的是垃圾收集器和用户程序同时执行。除了 CMS 和 G1 之外,其它垃圾收集器都是以串行的方式执行。

1.1 内存分配与回收策略

JVM 在进行 GC 时,并非每次都对堆内存(新生代、老年代;方法区)区域一起回收的,大部分时候回收的都是指新生代

针对 HotSpot VM 的实现,它里面的 GC 按照回收区域又分为两大类:部分收集Partial GC),整堆收集Full GC)。

  • 部分收集:不是完整收集整个 Java 堆的垃圾收集。其中又分为:
    • 新生代收集Minor GC / Young GC):只是新生代的垃圾收集。
    • 老年代收集Major GC / Old GC):只是老年代的垃圾收集。目前,只有 CMS GC 会有单独收集老年代的行为。很多时候 Major GC 会和 Full GC 混合使用,需要具体分辨是老年代回收还是整堆回收。
    • 混合收集Mixed GC):收集整个新生代以及部分老年代的垃圾收集。目前只有 G1 GC 会有这种行为。
  • 整堆收集:收集整个 Java 堆和方法区的垃圾。

1.2 Serial 收集器

  • -XX:+UseSerialGC
  • -XX:+UseSerialOldGC

Serial 是一个单线程收集器了。它的 “单线程” 的意义不仅仅意味着它只会使用一条垃圾收集线程去完成垃圾收集工作,更重要的是它在进行垃圾收集工作的时候必须暂停其他所有的工作线程( “Stop The World” ),直到它收集结束。

在这里插入图片描述

  • Serial 收集器由于没有线程交互的开销,自然可以获得很高的单线程收集效率。
  • Serial Old 收集器是 Serial 收集器的老年代版本,它同样是一个单线程收集器。它主要有两大用途:一种用途是在 JDK 1.5 以及以前的版本中与 Parallel Scavenge 收集器搭配使用,另一种用途是作为 CMS 收集器的后备方案。
  • 新生代采用 复制 算法,老年代采用 标记-整理 算法。

1.3 Parallel Scavenge 收集器

  • -XX:+UseParallelGC(新生代)
  • -XX:+UseParallelOldGC(老年代)

Parallel 收集器其实就是 Serial 收集器的 多线程版本,除了使用多线程进行垃圾收集外,其余行为(控制参数、收集算法、回收策略等等)和 Serial 收集器类似。默认的收集线程数CPU 核数 相同,当然也可以用参数(-XX:ParallelGCThreads)指定收集线程数,但是一般不推荐修改。

Parallel Scavenge 收集器关注点是 吞吐量(高效率的利用 CPU)。CMS 等垃圾收集器的关注点更多的是用户线程的 停顿时间(提高用户体验)。所谓吞吐量就是 CPU 中用于运行用户代码的时间与 CPU 总消耗时间的比值。Parallel Scavenge 收集器提供了很多参数供用户找到最合适的停顿时间或最大吞吐量,如果对于收集器运作不太了解的话,可以选择把内存管理优化交给虚拟机去完成也是一个不错的选择。

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

Parallel Old 收集器是 Parallel Scavenge 收集器的老年代版本。使用 多线程标记-整理 算法。在注重吞吐量以及 CPU 资源的场合,都可以优先考虑 Parallel Scavenge 收集器和 Parallel Old 收集器(JDK 8 默认的新生代和老年代收集器)。

1.4 ParNew 收集器

  • -XX:+UseParNewGC(新生代)

ParNew 收集器其实跟 Parallel 收集器很类似,区别主要在于它可以和 CMS 收集器配合使用。

新生代采用 复制 算法。

1.5 CMS 收集器

  • -XX:+UseConcMarkSweepGC(老年代)

CMS(Concurrent Mark Sweep),Mark Sweep 指的是 标记-清除 算法。

CMS 收集器是一种以获取 最短回收停顿时间 为目标的收集器。它非常符合在注重用户体验的应用上使用,它是 HotSpot 虚拟机第一款真正意义上的并发收集器,它第一次实现了让垃圾收集线程与用户线程(基本上)同时工作

它的运作过程相比于前面几种垃圾收集器来说更加复杂一些。整个过程分为四个步骤:

  • 初始标记: 暂停所有的其他线程(STW),并记录下 GC Roots 直接能引用的对象,速度很快。
  • 并发标记: 并发标记阶段就是从 GC Roots 的直接关联对象开始遍历整个对象图的过程, 这个过程耗时较长但是不需要停顿用户线程, 可以与垃圾收集线程一起并发运行。因为用户程序继续运行,可能会有导致已经标记过的对象状态发生改变。
  • 重新标记: 重新标记阶段就是为了修正并发标记期间因为用户程序继续运行而导致标记产生变动的那一部分对象的标记记录(主要是处理漏标问题),这个阶段的停顿时间一般会比初始标记阶段的时间稍长,远远比并发标记阶段时间短。主要用到三色标记里的增量更新算法做重新标记。
  • 并发清理: 开启用户线程,同时 GC 线程开始对未标记的区域做清扫。这个阶段如果有新增对象会被标记为黑色不做任何处理。
  • 并发重置:重置本次 GC 过程中的标记数据。

在这里插入图片描述

CMS 主要优点:并发收集、低停顿。但是它有下面几个明显的缺点:

  • ⭕ 对 CPU 资源敏感(会和服务抢资源)。
  • ⭕ 无法处理浮动垃圾(在并发标记和并发清理阶段又产生垃圾,这种浮动垃圾只能等到下一次 GC 再清理了)。
  • ⭕ 它使用的 “标记-清除” 回收算法会导致收集结束时会有大量空间碎片产生,通过参数 -XX:+UseCMSCompactAtFullCollection 可以让 JVM 在执行完标记清除后再做整理,往往出现老年代空间剩余,但无法找到足够大连续空间来分配当前对象,不得不提前触发一次 Full GC。
  • ⭕ 执行过程中的不确定性,会存在上一次垃圾回收还没执行完,然后垃圾回收又被触发的情况,特别是在并发标记和并发清理阶段会出现,一边回收,系统一边运行,也许没回收完就再次触发 Full GC,也就是 “Concurrent Mode Failure”,此时会进入 “Stop The World”,用 Serial Old 垃圾收集器来回收。

1.6 G1 收集器

G1(Garbage-First)是一款面向服务端应用的垃圾收集器,在多 CPU 和大内存的场景下有很好的性能。

堆被分为新生代和老年代,其它收集器进行收集的范围都是整个新生代或者老年代,而 G1 可以直接对新生代和老年代一起回收。G1 把堆划分成多个大小相等的 独立区域Region),新生代和老年代不再物理隔离。
在这里插入图片描述
通过引入 Region 的概念,从而将原来的一整块内存空间划分成多个的小空间,使得每个小空间可以单独进行垃圾回收。这种划分方法带来了很大的灵活性,使得可预测的停顿时间模型成为可能。通过记录每个 Region 垃圾回收时间以及回收所获得的空间(这两个值是通过过去回收的经验获得),并维护一个优先列表,每次根据允许的收集时间,优先回收价值最大的 Region。

每个 Region 都有一个 Remembered Set,用来记录该 Region 对象的引用对象所在的 Region。通过使用 Remembered Set,在做可达性分析的时候就可以避免全堆扫描。

G1 收集器的运作大致可划分为以下几个步骤:

  • 初始标记Initial Marking):仅仅只是标记一下 GC Roots 能直接关联到的对象。
  • 并发标记Concurrent Marking):从 GC Roots 开始对堆中对象进行可达性分析,递归扫描整个堆里的对象图,找出要回收的对象,这阶段耗时较长,但可与用户程序并发执行。
  • 最终标记Final Marking):对用户线程做另一个短暂的暂停,用于处理并发阶段结束后仍遗留下来的最后那少量的 SATB(Snapshot At The Beginning,原始快照)记录。
  • 筛选回收Live Data Counting and Evacuation):负责更新 Region 的统计数据,对各个 Region 的回收价值和成本进行排序,根据用户所期望的停顿时间来制定回收计划,可以自由选择任意多个 Region 构成回收集,然后把决定回收的那一部分 Region 的存活对象复制到空的 Region 中,再清理掉整个旧 Region 的全部空间。这里的操作涉及存活对象的移动,是必须暂停用户线程,由多条收集器线程并行完成的。

它具备以下特点:

  • 并行与并发:G1 能充分利用 CPU、多核环境下的硬件优势,使用多个 CPU(CPU 或者 CPU 核心)来缩短 Stop-The-World 停顿时间。部分其他收集器原本需要停顿 Java 线程执行的 GC 动作,G1 收集器仍然可以通过并发的方式让 Java 程序继续执行。
  • 分代收集:虽然 G1 可以不需要其他收集器配合就能独立管理整个 GC 堆,但是还是保留了分代的概念。
  • 空间整合:与 CMS 的 “标记-清除” 算法不同,G1 从整体来看是基于 “标记-整理” 算法实现的收集器;从局部上来看是基于 “标记-复制” 算法实现的。
  • 可预测的停顿:这是 G1 相对于 CMS 的另一个大优势,降低停顿时间是 G1 和 CMS 共同的关注点,但 G1 除了追求低停顿外,还能建立可预测的停顿时间模型,能让使用者明确指定在一个长度为 M 毫秒的时间片段内,消耗在垃圾收集上的时间不得超过 N 毫秒。

在这里插入图片描述
G1 收集器在后台维护了一个优先列表,每次根据允许的收集时间,优先选择回收价值最大的 Region(这也就是它的名字 Garbage-First 的由来)。这种使用 Region 划分内存空间以及有优先级的区域回收方式,保证了 G1 收集器在有限时间内可以尽可能高的收集效率(把内存化整为零)。

从 JDK 9 开始,G1 垃圾收集器成为了默认的垃圾收集器

2.Full GC 的触发条件

对于 Minor GC,其触发条件非常简单,当 Eden 空间满时,就将触发一次 Minor GC。而 Full GC 则相对复杂,有以下条件:

  • 调用 System.gc() 只是建议虚拟机执行 Full GC,但是虚拟机不一定真正去执行。不建议使用这种方式,而是让虚拟机管理内存。
  • 老年代空间不足。老年代空间不足的常见场景为前文所讲的:大对象直接进入老年代、长期存活的对象进入老年代等。为了避免以上原因引起的 Full GC,应当尽量不要创建过大的对象以及数组。除此之外,可以通过 -Xmn 虚拟机参数调大新生代的大小,让对象尽量在新生代被回收掉,不进入老年代。还可以通过 -XX:MaxTenuringThreshold 调大对象进入老年代的年龄,让对象在新生代多存活一段时间。
  • 空间分配担保失败。使用复制算法的 Minor GC 需要老年代的内存空间作担保,如果担保失败会执行一次 Full GC。
  • JDK 1.7 及以前的永久代空间不足(1.7 之后元空间不足)。在 JDK 1.7 及以前,HotSpot 虚拟机中的方法区是用永久代实现的,永久代中存放的为一些 Class 的信息、常量、静态变量等数据。当系统中要加载的类、反射的类和调用的方法较多时,永久代可能会被占满,在未配置为采用 CMS GC 的情况下也会执行 Full GC。如果经过 Full GC 仍然回收不了,那么虚拟机会抛出 java.lang.OutOfMemoryError。为避免以上原因引起的 Full GC,可采用的方法为增大永久代空间或转为使用 CMS GC。
  • Concurrent Mode Failure。执行 CMS GC 的过程中同时有对象要放入老年代,而此时老年代空间不足(可能是 GC 过程中浮动垃圾过多导致暂时性的空间不足),便会报 Concurrent Mode Failure 错误,并触发 Full GC。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1458482.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Bert基础(一)--自注意力机制

1、简介 当下最先进的深度学习架构之一,Transformer被广泛应用于自然语言处理领域。它不单替代了以前流行的循环神经网络(recurrent neural network, RNN)和长短期记忆(long short-term memory, LSTM)网络,并且以它为基础衍生出了诸如BERT、GPT-3、T5等…

毕设(二)——NB-IOT通信模块(nb卡通信测试)+gps定位

文章目录 一、关于接线2月1日记录2月4日记录 二、网络连接测试三、HTTP通信3.1 网络调试3.2 nb-lot的连接测试 一、关于接线 如果pico的供电能力不行,可能会直接用4.2V的锂电池对右下引脚进行供电 这个模块只支持nb卡,我哭死,20块钱&#xff…

跟国外客户交流时怎么把英语说的更地道?

只要把中文逐字逐句翻译成对应的英文,就能讲好英语了吗? 并不!那样的话我们只需要Google翻译不就可以了。 说英语时,要把思维也调整到英语模式,才能够说得流畅、地道。 01 对初次见面的老外,问他叫什么&a…

HBase 进阶

参考来源: B站尚硅谷HBase2.x 目录 Master 架构RegionServer 架构写流程MemStore Flush读流程HFile 结构读流程合并读取数据优化 StoreFile CompactionRegion Split预分区(自定义分区)系统拆分 Master 架构 Master详细架构 1)Meta 表格介…

什么是采购到付款流程?如何借助采购管理软件提升效率

各自为政、分散的采购工具使从采购到付款流程复杂化。过时的采购解决方案成本高、不灵活、效率低,但大多数企业仍在 "凑合 "使用老式的采购工具。 根据 Paystream 2023 年采购洞察报告,80% 的企业仍在使用手动或半数字化工具来管理其 P2P 周期…

【Java EE初阶十五】网络编程TCP/IP协议(二)

1. 关于TCP 1.1 TCP 的socket api tcp的socket api和U大片的socket api差异很大,但是和前面所讲的文件操作很密切的联系 下面主要讲解两个关键的类: 1、ServerSocket:给服务器使用的类,使用这个类来绑定端口号 2、Socket&#xf…

跳过测试方法(测试类)(@Ignore)

1.什么情况下要使用跳过测试(测试类)方法? 写了一个测试方法但是不想执行 删掉该测试方法(测试类)注释该测试方法(测试类)使用Ignore注解 2.示例 2.1 必要工作 导入类库 import org.junit.Ignore; 2.2 使用Ignore注解跳过…

Mint-21.2 编译goocanvas时 No package gtk+-4.0 found错误

Linux Mint 21.2 系统自带了4版本的 gtk 库,64位与32并存。许多 Linux 团队都集中精力仅维护 64 位库了,Mint 团队还保持着 32 位同步维护,辛苦程度非同一般。安装完gtk4后,pkg-config 找到的是gtk4,不是gtk-4.0&#…

【快速搞定Webpack4】基本配置及开发模式介绍(二)

在开始使用webpack之前么,我们需要对Webpack的配置有一定的认识。 一、5大核心概念 1. enty(入口) 指示webpack从哪个文件开始打包 2. output(输出) 指示webpack打包完的文件输出到哪里去,如何命名等 …

【MATLAB源码-第140期】基于matlab的深度学习的两用户NOMA-OFDM系统信道估计仿真,对比LS,MMSE,ML。

操作环境: MATLAB 2022a 1、算法描述 深度学习技术在无线通信领域的应用越来越广泛,特别是在非正交多址接入(NOMA)和正交频分复用(OFDM)系统中,深度学习技术被用来提高信道估计的性能和效率。…

Mysql事务原理与优化

概述 我们的数据库一般都会并发执行多个事务,多个事务可能会并发的对相同的一批数据进行增删改查操作,可能就会导致我们说的脏写、脏读、不可重复读、幻读这些问题。 这些问题的本质都是数据库的多事务并发问题,为了解决多事务并发问题&…

python 基础知识点(蓝桥杯python科目个人复习计划46)

今日复习内容:重做一遍复习题(一部分) 例题1:小蓝的漆房 题目描述: 小蓝是一位有名的漆匠,他的朋友小桥有一个漆房,里面有一条长长的走廊,走廊两旁有许多相邻的房子,每…

文件IO,目录IO的学习

一&#xff0c;头文件的添加 #ifndef _HEAD_H_ //防止重新定义宏 #define _HEAD_H_#include<stdio.h> #include<sys/stat.h> #include<sys/types.h> #include<fcntl.h> #include<unistd.h> #include<string.h>#endif…

【C语言】Leetcode 27.移除元素

一、代码实现 如果不考虑O(1)的空间复杂度的话我们可以再创建数组来进行遍历解决该问题&#xff0c;但是在要求之下该做法无法通过。于是我们可以用双指针来解决&#xff0c;最坏的情况时间复杂度为O(N)。 int removeElement(int* nums, int numsSize, int val) {int src 0;…

http相关概念以及apache的功能

概念 互联网&#xff1a;是网络的网络&#xff0c;是所有类型网络的母集 因特网&#xff1a;世界上最大的互联网网络 万维网&#xff1a;www &#xff08;不是网络&#xff0c;而是数据库&#xff09;是网页与网页之间的跳转关系 URL:万维网使用统一资源定位符&#xff0c;…

【C#】使用代码实现龙年春晚扑克牌魔术(守岁共此时),流程描述篇

欢迎来到《小5讲堂》 大家好&#xff0c;我是全栈小5。 这是《C#》系列文章&#xff0c;每篇文章将以博主理解的角度展开讲解&#xff0c; 特别是针对知识点的概念进行叙说&#xff0c;大部分文章将会对这些概念进行实际例子验证&#xff0c;以此达到加深对知识点的理解和掌握。…

【C语言】初步认识结构体

1.结构体诞生的由来 C语言已经提供了内置类型&#xff0c;如&#xff1a;char、short、int、long、float、double等&#xff0c;但是只有这些内置类型还是不够的&#xff0c;假设我想描述学生&#xff0c;描述⼀本书&#xff0c;这时单一的内置类型是不行的。描述⼀个学生需要名…

从数据库中读取文件导出为Excel

使用的库&#xff08;org.apache.poi&#xff09; 在poi包中有Apache提供的各种分类文件&#xff0c;如下 结构功能HSSF读写Microsoft Excel XLS文件XSSF读写Microsoft Excel OOXML XLSX文件HWPF读写Microsoft Word DOC文件HSLF读写Microsoft PowerPoint文件 下面以XSSF为例&…

优思学院|精益思想如何识别价值流?【案例分析】

精益思想是一种为了提高效率、减少浪费的管理哲学&#xff0c;精益思想强调在整个生产过程中识别并消除一切不创造价值的步骤。 价值流分析是精益思想中的一个核心概念&#xff0c;通过深入分析特定产品从原材料到最终交付给顾客的全过程&#xff0c;来识别并削减浪费&#xf…

回避型人格适合什么职业?如何改善回避型人格?

回避型人格最突出的特点,就是对外界的排斥极度敏感&#xff0c;他们非常害怕别人的不认可&#xff0c;也特别害惧失败&#xff0c;因此不敢与人交往&#xff0c;同时也害怕新事物。因为受到这一性格的影响&#xff0c;他们极度缺乏社交能力&#xff0c;也一直在否定自身能力。 …