JVM垃圾回收器详解

垃圾回收器

JDK 默认垃圾收集器(使用 java -XX:+PrintCommandLineFlags -version 命令查看):

  • JDK 8:Parallel Scavenge(新生代)+ Parallel Old(老年代)

  • JDK 9 ~ JDK20: G1

堆内存中对象的特性:

  • 系统中的大部分对象,都是创建出来之后很快就不再使用可以被回收,比如用户获取订单数据,订单数据返回给用户之后就可以释放了。

  • 老年代中会存放长期存活的对象,比如Spring的大部分bean对象,在程序启动之后就不会被回收了。

  • 在虚拟机的默认设置中,新生代大小要远小于老年代的大小。

分代GC算法将堆分成年轻代和老年代主要原因有:【降低垃圾回收对系统的影响】

1、可以通过调整年轻代和老年代的比例来适应不同类型的应用程序,提高内存的利用率和性能

2、新生代和老年代使用不同的垃圾回收算法,新生代一般选择复制算法【不会有内存碎片,吞吐量比标记算法高】,老年代可以选择标记-清除和标记-整理算法,由程序员来选择灵活度较高

3、分代的设计中允许只回收新生代(minor gc),如果能满足对象分配的要求就不需要对整个堆进行回收(full gc),STW时间就会减少。【吞吐量增大。因为FullGC耗时长】避免FullGC

  • 比如在新生代中,每次收集都会有大量对象死去,所以可以选择”标记-复制“算法,只需要付出少量对象的复制成本就可以完成每次垃圾收集。

  • 而老年代的对象存活几率是比较高的(需要回收的少),而且没有额外的空间对它进行分配担保,所以我们必须选择“标记-清除”或“标记-整理”算法进行垃圾收集。

垃圾回收器是垃圾回收算法的具体实现

由于垃圾回收器分为年轻代和老年代,除了G1之外其他垃圾回收器必须成对组合进行使用

具体的关系图如下:

年轻代-Serial(串行)垃圾回收器
  • 新生代采用标记-复制算法,老年代采用标记-整理算法。

复制算法

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

  • 没有线程交互的开销,自然可以获得很高的单线程收集效率。Serial 收集器对于运行在 Client 模式下的虚拟机来说是个不错的选择。

老年代-SerialOld垃圾回收器

标记-整理算法

CMS 收集器的后备方案

Serial 收集器的老年代版本

年轻代-ParNew垃圾回收器
  • 新生代采用标记-复制算法,老年代采用标记-整理算法。

复制算法

Serial 收集器的多线程版本,除了使用多线程进行垃圾收集外,其余行为(控制参数、收集算法、回收策略等等)和 Serial 收集器完全一样。

运行在 Server 模式下的虚拟机的首要选择

并行和并发概念补充:

  • 并行(Parallel):指多条垃圾收集线程并行工作,但此时用户线程仍然处于等待状态

  • 并发(Concurrent):指用户线程与垃圾收集线程同时执行(但不一定是并行,可能会交替执行),用户程序在继续运行,而垃圾收集器运行在另一个 CPU 上。【CMS真正意义上的并发收集器

老年代- CMS(Concurrent Mark Sweep)垃圾回收器

【有设计上的缺陷,所以JDK14废除了】

标记-清除算法【一般不会老年代单独标记清除,是在标记清除的基础上在FullGC时整理】

STW:初始标记、重新标记

以获取最短回收停顿时间为目标的收集器

第一次实现了让垃圾收集线程与用户线程(基本上)同时工作。【并发】

初始标记和重新标记不是会暂停用户线程

CMS执行步骤:

1.初始标记,用极短的时间标记出GC Roots能直接关联到的对象。

2.并发标记, 标记所有的对象,用户线程不需要暂停

3.重新标记,由于并发标记阶段有些对象会发生了变化,存在错标、漏标等情况,需要重新标记。【STW时间:初始标记 < 重新标记 << 并发标记】

4.并发清理,清理死亡的对象,用户线程不需要暂停。

缺点:【标记清除,但有FullGC】

1、CMS使用了标记-清除算法,在垃圾收集结束之后会出现大量的内存碎片,CMS会在Full GC时进行碎片的整理。这样会导致用户线程暂停,可以使用-XX:CMSFullGCsBeforeCompaction=N 参数(默认0)调整N次Full GC之后再整理。【弥补措施,但还是跑不掉】

2.、无法处理在并发清理过程中产生的“浮动垃圾”,不能做到完全的垃圾回收。【并发清理过程中产生新垃圾,没有标记】

3、如果老年代内存不足无法分配对象,CMS就会退化成Serial Old单线程回收老年代。【降级策略】

年轻代-Parallel(并行) Scavenge垃圾回收器
  • 新生代采用标记-复制算法,老年代采用标记-整理算法。

关注吞吐量,自动调整堆内存

复制算法、自动调整堆【提供了很多参数供用户找到最合适的停顿时间或最大吞吐量】

【垃圾回收会产生STW】

常用参数:

Parallel Scavenge允许手动设置最大暂停时间和吞吐量。Oracle官方建议在使用这个组合时,不要设置堆内存的最大值,垃圾回收器会根据最大暂停时间和吞吐量自动调整内存大小。

  • 最大暂停时间,-XX:MaxGCPauseMillis=n 设置每次垃圾回收时的最大停顿毫秒数

  • 吞吐量,-XX:GCTimeRatio=n 设置吞吐量为n(用户线程执行时间 = n/n + 1)

  • 动调整内存大小, -XX:+UseAdaptiveSizePolicy设置可以让垃圾回收器根据吞吐量和最大停顿的毫秒数自动调整内存大小

老年代-Parallel Old垃圾回收器

标记-整理算法【一般不会老年代单独标记清除,是在标记清除的基础上在FullGC时整理】

  • 注重吞吐量以及 CPU 资源

G1垃圾回收器

面向服务器的垃圾收集器,主要针对配备多核处理器及大容量内存的机器. 以极高概率满足 GC 停顿时间要求的同时,还具备高吞吐量性能特征.

特征:

并行与并发:G1 能充分利用 CPU、多核环境下的硬件优势,使用多个 CPU(CPU 或者 CPU 核心)来缩短 Stop-The-World 停顿时间。部分其他收集器原本需要停顿 Java 线程执行的 GC 动作,G1 收集器仍然可以通过并发的方式让 java 程序继续执行。

分代收集:虽然 G1 可以不需要其他收集器配合就能独立管理整个 GC 堆,但是还是保留了分代的概念。

空间整合:与 CMS 的“标记-清除”算法不同,G1 从整体来看是基于“标记-整理”算法实现的收集器;从局部上来看是基于“标记-复制”算法实现的。

可预测的停顿:这是 G1 相对于 CMS 的另一个大优势,降低停顿时间是 G1 和 CMS 共同的关注点,但 G1 除了追求低停顿外,还能建立可预测的停顿时间模型,能让使用者明确指定在一个长度为 M 毫秒的时间片段内,消耗在垃圾收集上的时间不得超过 N 毫秒。

JDK9之后默认的垃圾回收器是G1(Garbage垃圾 First)垃圾回收器

  • Parallel Scavenge关注吞吐量,允许用户设置最大暂停时间 ,但是会减少年轻代可用空间的大小。

  • CMS关注暂停时间【追求变短】,但是吞吐量方面会下降。

而G1设计目标就是将上述两种垃圾回收器的优点融合:【在后台维护了一个优先列表,每次根据允许的收集时间,优先选择回收价值最大的 Region】

1.支持巨大的堆空间回收,并有较高的吞吐量。

2.支持多CPU并行垃圾回收。

3.允许用户设置最大暂停时间。

JDK9之后强烈建议使用G1垃圾回收器。

  • G1出现之前的垃圾回收器,年轻代和老年代一般是连续的,如下图:

  • G1的整个堆会被划分成多个大小相等的区域,称之为区Region,区域不要求是连续的。分为Eden、Survivor、Old区。Region的大小通过堆空间大小/2048计算得到,也可以通过参数-XX:G1HeapRegionSize=32m指定(其中32m指定region大小为32M),Region size必须是2的指数幂,取值范围从1M到32M

G1垃圾回收有两种方式:

1、年轻代回收(Young GC)

2、混合回收(Mixed GC)

年轻代回收

年轻代回收(Young GC),回收Eden区和Survivor区中不用的对象。会导致STW,G1中可以通过参数-XX:MaxGCPauseMillis=n(默认200) 设置每次垃圾回收时的最大暂停时间毫秒数,G1垃圾回收器会尽可能地保证暂停时间。

1、新创建的对象会存放在Eden区。当G1判断年轻代区不足(max默认60%),无法分配对象时需要回收时会执行Young GC。

2、标记出Eden和Survivor区域中的存活对象

3、根据配置的最大暂停时间选择某些区域将存活对象复制【复制,没有内存碎片】到一个新的Survivor区中(年龄+1),清空这些区域。

  • G1在进行Young GC的过程中会去记录每次垃圾回收时每个Eden区和Survivor区的平均耗时,以作为下次回收时的参考依据。这样就可以根据配置的最大暂停时间计算出本次回收时最多能回收多少个Region区域了。

比如 -XX:MaxGCPauseMillis=n(默认200),每个Region回收耗时40ms,那么这次回收最多只能回收4个Region。

4、后续Young GC时与之前相同,只不过Survivor区中存活对象会被搬运到另一个Survivor区

5、当某个存活对象的年龄到达阈值(默认15),将被放入老年代。

6、部分对象如果大小超过Region的一半,会直接放入老年代,这类老年代被称为Humongous区。比如堆内存是4G,每个Region是2M,只要一个大对象超过了1M就被放入Humongous区,【如果对象过大会横跨多个Region】。、

7、多次回收之后,会出现很多Old老年代区,此时总堆占有率达到阈值时。(-XX:InitiatingHeapOccupancyPercent默认45%)会触发混合回收MixedGC。回收所有年轻代和部分老年代的对象以及大对象区。采用复制算法来完成。

混合回收

混合回收分为:初始标记(initial mark)、并发标记(concurrent mark)、最终标记(remark或者Finalize Marking)、并发清理(cleanup)【重新标记和CMS不一样】

G1对老年代的清理会选择存活度最低的区域来进行回收,这样可以保证回收效率最高,这也是G1(Garbage first)名称的由来。最后清理阶段使用复制算法,不会产生内存碎片。【不会全部清理,效率变快】

  • 漏标和CMS不一样,只补充由于他的引用改变了导致漏标的。【旧的】所以比CMS快

  • 注意:如果清理过程中发现没有足够的空Region存放转移的对象,会出现Full GC。单线程执行标记-整理算法,此时会导致用户线程的暂停。所以尽量保证应该用的堆内存有一定多余的空间。

总结

垃圾回收器的组合关系虽然很多,但是针对几个特定的版本,比较好的组合选择如下:

JDK8及之前:

ParNew + CMS(关注暂停时间)、Parallel Scavenge + Parallel Old (关注吞吐量)、 G1(JDK8之前不建议,较大堆并且关注暂停时间)

JDK9之后:

G1(默认)

从JDK9之后,由于G1日趋成熟,JDK默认的垃圾回收器已经修改为G1,所以强烈建议在生产环境上使用G1。

(此处)并行和并发概念补充
  • 并行(Parallel):指多条垃圾收集线程并行工作,但此时用户线程仍然处于等待状态。

  • 并发(Concurrent):指用户线程与垃圾收集线程同时执行(但不一定是并行,可能会交替执行),用户程序在继续运行,而垃圾收集器运行在另一个 CPU 上。【CMS真正意义上的并发收集器

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

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

相关文章

如何将HEVC格式的视频转换为无损、未压缩的MP4格式视频?

在和大家分享视频格式转换之前&#xff0c;先跟大家分享一下HEVC格式的视频到底是什么文件&#xff1f;压缩原理是什么&#xff1f;了解了它的本质之后&#xff0c;我们就可以知道如何保证视频高清无损了。 如何将HEVC格式的视频转换为无损、未压缩的MP4格式视频&#xff1f; …

Sora模型:释放创意产业文本到视频AI的潜力

Sora&#xff0c;这个由OpenAI在2024年推出的文本到视频生成模型&#xff0c;不仅能够将文字描述转化为生动的视频内容&#xff0c;而且还能保持视频一分钟之久的连贯性和高质量&#xff0c;这在之前是难以想象的。 尽管AI在图像和文本理解上已取得巨大进步&#xff0c;但将这…

捷配PCB 6个PCB板材关键参数解读技巧

PCB板材是指覆铜基板&#xff0c;是制造电路板的最主要材料。 板材的一些关键性能参数对电路板的生产加工、元器件贴装焊接、电子产品的功能实现以及产品的使用环境或寿命等都将产生一定程度的影响&#xff0c;所以掌握板材的关键参数在实际应用中非常有必要。 PCB板材的关键性…

【Linux】进程7——查看进程

1.为什么进程管理这么重要呢&#xff1f; 这是因为&#xff1a; 首先&#xff0c;我们在操作系统时的各项任务其实都是经过某个PID来完成的&#xff08;包括你的bash环境&#xff09;&#xff0c;因此&#xff0c;能不能执行某项任务&#xff0c;就与该进程的权限有关了。再来…

PMON的解读和开发

提示&#xff1a;龙芯2K1000PMON相关记录 文章目录 1 PMON的发展和编译环境PMONPMON2000 2 PMON2000的目录结构3 Targets目录的组成4 PMON编译环境的建立5 PMON2000的框架6 异常向量表7 Pmon的空间分配8 PMON的汇编部分(starto.S或sbdreset.S)的解读Start.SC代码部分dbginit 9 …

20个实验数据创造AI蛋白质里程碑!上海交大联合上海AI Lab发布FSFP,有效优化蛋白质预训练模型

蛋白质&#xff0c;这些微小而强大的生物分子&#xff0c;是生命活动的基础&#xff0c;在生物体内扮演着多种角色。然而&#xff0c;要精确地调整和优化蛋白质功能&#xff0c;以适应特定的工业或医疗需求&#xff0c;却是一项极具挑战性的任务。传统上&#xff0c;科学家们依…

MSI打包后门成安装包

目录 浏览器下载地址 启动>next 选择后门所在路径&#xff0c;和生成安装包后存放路径 next>Hidden 配置变量 Look up随便找个伪装&#xff0c;然后点击一下Creat New ​注册表Registry导入 ​点击否&#xff0c;不购买专业版 ​安装包生成成功​编辑 浏览器下…

【昇思25天学习打卡营打卡指南-第二十二天】GAN图像生成

GAN图像生成 模型简介 生成式对抗网络(Generative Adversarial Networks&#xff0c;GAN)是一种生成式机器学习模型&#xff0c;是近年来复杂分布上无监督学习最具前景的方法之一。 最初&#xff0c;GAN由Ian J. Goodfellow于2014年发明&#xff0c;并在论文Generative Adve…

交叉熵损失函数的使用目的(很肤浅的理解)

第一种使用方法 import torch from torch import nn # Example of target with class indices loss nn.CrossEntropyLoss() input torch.randn(3, 5, requires_gradTrue) target torch.empty(3, dtypetorch.long).random_(5) output loss(input, target) output.backward(…

[Python自动化办公]--从网页登录网易邮箱进行邮件搜索并下载邮件附件

[Python自动化办公]–从网页登录网易邮箱进行邮件搜索并下载邮件附件 使用说明 ​ 本文使用Python的selenium库进行操作邮箱登录、固定名称搜索邮件并下载附件&#xff0c;Python版本&#xff1a;3.9.16, selenium版本&#xff1a;4.19.0&#xff0c;EdgeBrowser版本:126.0.2…

无线网的ip地址固定吗

在数字化日益普及的今天&#xff0c;无线网络已成为我们生活与工作中不可或缺的一部分。然而&#xff0c;对于许多非专业用户来说&#xff0c;无线网络背后的技术细节仍然充满了神秘感。其中&#xff0c;一个常见的问题是&#xff1a;无线网的IP地址是固定的吗&#xff1f;本文…

使用“nvm use 版本号“命令无效

使用"nvm use 版本号"命令无效 为什么无效?解决 为什么无效? 解决 将这个nodejs文件夹删除,然后在运行nvm use 版本号,则 node生效.

QT开发积累——qt中的注释和多行注释的几种方式,函数方法注释生成

目录 引出qt中的注释和多行注释方法的注释生成 总结日积月累&#xff0c;开发集锦方法参数加const和不加const的区别方法加static和不加static的区别Qt遍历list提高效率显示函数的调用使用&与不使用&qt方法的参数中使用&与不使用&除法的一个坑 项目创建相关新建…

window下载安装clang

执行clang报错&#xff1a; c:/>clang test.cclang: warning: unable to find a Visual Studio installation; try running Clang from a developer command prompt [-Wmsvc-not-found] clang: error: unable to execute command: program not executable clang: error: li…

数据隐私: 什么是数据隐私以及如何保护数据安全?

什么是数据隐私&#xff1f; 数据隐私&#xff08;或信息隐私&#xff09;是数据保护的一个领域。它指的是个人可以决定何时、如何以及在多大程度上与他人分享或交换他们的个人数据。 换句话说&#xff0c;数据隐私围绕着用户的个人数据如何被收集、存储、管理和与第三方共享…

Win-ARM联盟的端侧AI技术分析

Win-ARM联盟&#xff0c;端侧AI大幕将起 微软震撼发布全球首款AI定制Windows PC——Copilot PC&#xff0c;搭载全新NPU与重塑的Windows 11系统&#xff0c;纳德拉盛赞其为史上最快、最强、最智能的Windows PC。该设备算力需求高达40TOPS&#xff0c;支持语音翻译、实时绘画、文…

NesT : 嵌套层次Transformer

探讨了在不重叠的图像块上嵌套基本局部变换的思想,并以分层的方式对它们进行聚合。发现块聚合功能在实现跨块非局部信息通信中起着至关重要的作用。 这个观察结果引导我们设计一个简化的体系结构,它需要在原始视觉转换器上进行少量的代码更改。所提出的明智选择的设计有三个好…

【Spring Boot 教程:从入门到精通】掌握 Spring Boot 开发技巧与窍门(一)-java语法(1)

一些Java基本语法的基本介绍&#xff0c;语法更新结束会紧跟项目实战&#xff0c;后续会持续在该专栏进行更新&#xff01;&#xff01;&#xff01; 目录 前言 一、基本概念 1.JDK、JRE、JVM的关系&#xff1a; 2.JDK版本选择 3.Java代码的编译运行流程 4.JSE、JEE、J…

SolidWorks滚花螺栓制作-cnblog

目标 规划基准图形 确定尺寸&#xff0c;单位mm 我 对固定好的图形进行旋转 倒角 设置螺纹 注意改变深度为15mm 收尾位置补全 滚花 建立基准面 制作多边形 添加穿透 扫描切除 圆周阵列 成品完成

[AI 快手 LivePortrait] 引领高效肖像动画新时代

快手推出了 LivePortrait&#xff0c;具有拼接和重定向控制的高效肖像动画。 快速开始 下载代码&#xff0c;准备环境 git clone https://github.com/KwaiVGI/LivePortrait cd LivePortrait# create env using conda conda create -n LivePortrait python3.9.18 conda activ…