深入理解Java虚拟机 --- 垃圾回收器

news/2024/11/8 13:22:35/文章来源:https://www.cnblogs.com/ayu0v0/p/18534872

Serial收集器

HotSpot虚拟机运行在客户端模式下的默认新生代收集器。

类型:单线程串行垃圾回收器

垃圾收集算法:复制算法

作用区域:新生代

特点:

1、只会用单个线程去完成垃圾收集工作,用户线程会STW,直到收集结束。

2、没有线程交互,专心做垃圾收集,获得最高的单线程收集效率。

ParNew收集器

类型:多线程并行垃圾回收器

垃圾收集算法:复制算法

作用区域:新生代

本质上就是Serial收集器的并行版本。

特点:

1、能与CMS收集器搭配使用。

Parallel Scavenge收集器

类型:多线程并行垃圾回收器

垃圾收集算法:复制算法

作用区域:新生代

特点:

1、是以吞吐量优先的垃圾回收器。(吞吐量=用户运行代码时间/用户运行代码时间+垃圾收集时间)

2、不能与CMS收集器搭配使用。

3、内置有一个 PS MarkSweep收集器,但是实现原理跟Serial实现基本一样。

为什么CMS只能和ParNew搭配使用,而不能和Parallel Scavenge搭配使用?

就性能来看,Parallel Scavenge它的性能会比ParNew的性能要好一些。

但是CMS只能和ParNew搭配使用,原因如下:

1、CMS的设计目标是低延迟,Parallel Scavenge的设计目标是高吞吐量。

2、Parallel Scavenge没有使用HotSpot的分代框架,而CMS使用了HotSpot的分代框架。(ParNew使用了HotSpot的分代框架)

Serial Old收集器

类型:单线程串型收集器

垃圾收集算法:标记-整理算法

作用区域:老年代

Parallel Old收集器

类型:多线程并行收集器

垃圾收集算法:标记-整理算法

作用区域:老年代

特点:

1、缓解了Parallel Scanvenge的尴尬局面。(在其出之前Parallel Scanvenge只能和Serial搭配使用)

CMS收集器

这款收集器是HotSpot虚拟机中第一款真正意义上的并发收集器,它第一次实现了让垃圾收集线程与用户线程同时工作。

CMS收集器的关注点是尽可能缩短垃圾收集时用户线程的停顿时间。停顿时间越短(低延迟)就越适合与用户交互的程序,良好的响应速度能提升用户体验。

类型:多线程并发收集器

垃圾收集算法:标记-清除算法

作用区域:老年代

工作原理

image.png

  • 初始标记阶段:所有工作线程都会因为"Stop-the-World"机制而短暂暂停,这个阶段主要任务仅仅只是标记出GC Roots能直接关联到的对象

  • 并发标记阶段:从GC Roots的直接关联对象开始遍历整个对象图的过程,这个过程耗时较长但是不需要用户线程停顿。扫描完成后,这个过程可能会造成对象引用的改变。CMS使用了增量标记的技术,把改变的都引用发起者(黑色对象)存储起来。

  • 重新标记阶段:主要是处理并发阶段中存储起来的黑色对象,在STW的前提下,重新以他们为根进行标记。

  • 并发清除阶段:这个阶段清除掉标记阶段判断已经死亡的对象,释放内存空间。这个阶段可以与用户线程并发。

为什么采用标记-清除算法?

因为在清除过程中,GC线程是跟用户并发的,如果使用复制或标记-整理算法会造成对象内存地址的改变,那么会造成用户持有原先的引用而无法访问到对象的情况。

特点

1、触发CMS垃圾回收器时需要预留一定的空间来支持用户创建对象。

触发的阙值我们可以设置,但是在极端情况下,如果设置阙值过高,造成无法满足程序分配对象,那么虚拟机就会被迫启动Serial Old收集器来进行收集,这就会造成长时间的STW了。

2、会产生浮动垃圾

3、进行Full GC时,会进行内存碎片的整理

4、CMS对CPU资源非常敏感,在并发阶段时,虽然不会造成用户线程的STW,但是会因为占有CPU资源,而导致应用程序变慢,降低总吞吐量。

G1垃圾收集器

具有跨时代意义的垃圾收集器,设计思想:局部收集、基于Region的内存布局形式

设计目的:回收垃圾最大化。

作用区域:整个堆

垃圾收集算法:从整体上来看是标记-整理算法。但从两个Region的角度来看,是标记-复制算法。

Region

image.png

G1保留了年轻代和老年代的概念,但新生代和老年代不再是固定的了,而是一系列不需要连续的动态集合。

其中,Homongous区域主要用来存放大对象。G1认为只要大小超过了一半的Region区域的对象就称为大对象。大多数情况下,G1把Homongous当成老年代看待。

设置H区域的原因

之前遇到大对象且年轻代Eden空间不够的话,那么会将大对象放到老年代,那么这个大对象得等到Old GC或者Full GC才能得以清理。

而设置H区之后:1、避免了内存碎片 2、提高了回收大对象的效率

工作原理

  • 初始标记阶段:所有工作线程都会因为"Stop-the-World"机制而短暂暂停,这个阶段主要任务仅仅只是标记出GC Roots能直接关联到的对象

  • 并发标记阶段:从GC Root开始对堆中对象进行可达性分析,这个过程与用户线程并发执行。扫描完成后,这个过程中可能会存在对象引用的改变,G1使用原始快照(STAB)方式来避免出现漏标的情况。

  • 重新标记阶段:主要处理并发标记过程中的STAB记录,在STW的前提下,以他们为根进行重新标记。

  • 清除阶段:这个阶段需要用户线程STW。这个阶段清除掉标记阶段判断已经死亡的对象,释放内存空间。(使用的是复制算法)

问题

跨Region的引用问题:

当最开始我们使用分代模型的时候,只需要注意跨代引用,我们解决的思路是通过记忆集统计老年代到年轻代的引用即可。

而跨Region,我们就需要记录得跟复杂了。解题思路还是通过记忆集来记录跨Region引用,通过空间换时间的思路来避免全堆作为GC Root扫描。但是这个记忆集就需要每个Region都去维护自己独特的一个了,每个Region的记忆集不仅要记录我引用了谁,也要记录谁引用了我。

所以,记忆集造成了比较大的空间浪费。(10%~20%的堆空间浪费)

并发标记阶段如何避免漏标问题:

漏标:把存活的对象给他误删了。

G1使用了原始快照来解决漏标问题。当灰色对象要解开和白色对象的引用时,把白色对象记录下来。并在后面以他们为根,去扫描,让他们存活。(思路:就是以可能存在浮动垃圾的下,减少扫描的时间。)

Young GC & Mixed GC

G1通过构造一个可预测的时间模型,来在特定的时间内收获最高的垃圾。

那么在收集时,就不会只局限于年轻代了,当涉及多个代时,我们称为Mixed GC。

当只涉及年轻代时,我们还是称为Young GC。

ZGC垃圾收集器

概述

ZGC是JDK11推出的低延迟垃圾回收器。

设计目标:

1、停顿时间不超过10ms(低停顿)

2、停顿时间不会随着堆大小或者活跃对象的大小而增加。

适用场景:大内存低延迟服务

前者GC的痛点

前者的GC在STW这块都不是特别友善,所以在一些低延迟服务造成了性能困扰。

CMS(ParNew)与G1停顿时间瓶颈

ParNew和G1使用的都是标记-复制算法。

瓶颈定位→复制阶段中的转移阶段中复制对象。

复制阶段中转移阶段是STW的,转移阶段需要分配新内存和复制对象的成员变量。其中内存分配比较快,但是在复制一些复杂对象的时候耗时会比较长。

为什么转移阶段不能和用户并发执行呢?

主要是无法解决转移过程中精确定位对象地址的问题。如果并发执行,那么会导致用户访问不到具体对象。

ZGC的原理

全并发

ZGC采用标记-复制算法。不过ZGC在标记、转移和重定位阶段几乎都是并发的。

image.png

ZGC只有三个STW阶段:初始标记,再标记,初始转移。其中,初始标记和初始转移分别都只需要扫描所有GC Roots,其处理时间和GC Roots的数量成正比,一般情况耗时非常短;再标记阶段STW时间很短,最多1ms,超过1ms则再次进入并发标记阶段。即,ZGC几乎所有暂停都只依赖于GC Roots集合大小停顿时间不会随着堆的大小或者活跃对象的大小而增加。与ZGC对比,G1的转移阶段完全STW的,且停顿时间随存活对象的大小增加而增加

ZGC的技术

着色指针

image.png

着色指针是一种将信息存储在指针中的技术。

当应用程序创建对象时,首先在堆空间申请一个虚拟地址。同时会在M0、M1、Remapped地址空间分别申请一个虚拟地址,且三个虚拟地址对应同一个物理地址但这三个虚拟地址在同一时间只有一个空间有效

读屏障

Object o = obj.FieldA   // 从堆中读取引用,需要加入屏障
<Load barrier>
Object p = o  // 无需加入屏障,因为不是从堆中读取引用
o.dosomething() // 无需加入屏障,因为不是从堆中读取引用
int i =  obj.FieldB  //无需加入屏障,因为不是对象引用

ZGC中读屏障的代码作用:在对象标记和转移过程中,用于确定对象的引用是否满足条件,并做出对应的动作。

ZGC的并发处理过程

1、初始化:ZGC初始化之后,整个内存空间的地址视图被设置成Remapped。程序正常运行,在内存中分配对象,满足一定条件后垃圾回收启动,进入标记阶段。

2、并发标记阶段:第一次进入标记阶段时视图为M0,如果对象被GC标记线程或者应用线程访问过,那么就讲对象的地址视图从Remapped调整为M0。所以,在标记阶段之后,如果在M0就说明对象是活跃的,如果是在Remapped就说明对象是不活跃的。

3、并发转移阶段:标记结束后就进入转移阶段,此时地址视图再次被设置为Remapped,如果对象被GC标记线程或者应用程序访问过,那么会从M0调整为Remapped。

其实,在标记阶段存在两个地址视图M0和M1,上面的过程显示只用了一个地址视图。之所以设计成两个,是为了区别前一次标记和当前标记。也即,第二次进入并发标记阶段后,地址视图调整为M1,而非M0。

着色指针和读屏障技术不仅应用在并发转移阶段,还应用在并发标记阶段:将对象设置为已标记,传统的垃圾回收器需要进行一次内存访问,并将对象存活信息放在对象头中;而在ZGC中,只需要设置指针地址的第42~45位即可,并且因为是寄存器访问,所以速度比访问内存更快。

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【补档】玄武550电源怎么样? - 约呼的回答 - 知乎

【补档】玄武550电源怎么样? - 约呼的回答 - 知乎 约呼 一个路过的图吧用户 低预算整机非常推荐,高预算慎选。 低预算整机非常推荐,高预算慎选。 优点不少,缺点也有。 先说优点: 价格上来说便宜大碗,用料不错,部分型号反向虚标,比如550v4其实是按650w规格用料来做的,拆…

打造吸睛开场白:六招教你瞬间抓住客户心弦

开场白是在初次接触客户的头30秒至1分钟时间内,销售人员用以吸引目标客户注意力的简短言辞,通常涵盖前几句关键对话。 为了设计出一个引人入胜的开场白,以下策略值得尝试: 赞美客户赞美是人际交往中的润滑剂,恰当的赞美能迅速引起客户的关注。可以从客户的外观、着装、气质…

MM--项目中遇到的一些问题记录

采购订单: 创建采购订单时,供应商对应的信息记录已失效,但是切换供应商之后价格不会自动更新成0 1.SU01-查看用户对应的采购缺省值2.SPRO-维护采购缺省值 采购订单收货的时候,提示无符合条件的行项目 经打断点发现是由于程序中判断时公司间的内部交易所导致的,根本原因是因为采…

C#代码扫描工具SonarQube安装

前言 安装环境:Windows10+SonarQube 9.9.7 LTA Community Edition+jdk17+PostgreSQL 16.4+SonarScanner for .NET 9.0.1 在安装SonarQube 前需要搭建好jdk环境,这里我用的版本是jdk17,之前用过jdk1.8、jdk11和jdk21都失败了。还需提前安装第三方数据库,我用的是PostgreSQL …

数据结构 --树

定义 树是n(n>=0)个结点的有限集。n=0时,称为空树。在任意一棵树非空树中应满足: (1) 有且仅有一个特定的称为根 (root) 的结点 (2) 当时,其余结点可分为个互不相交的有限集,其中每一个集合本身又是一颗树,并且称为根的子树。 基本概念 结点的度:一个结点拥有的子树的…

人工智能--自然语言处理简介

上一篇:《人工智能模型训练中的数据之美——探索TFRecord》 序言:自然语言处理(NLP)是人工智能中的一种技术,专注于理解基于人类语言的内容。它包含了编程技术,用于创建可以理解语言、分类内容,甚至生成和创作人类语言的新作品的模型。在接下来的几章中,我们将会探讨这…

精选 Top10 开源调度工具,解锁高效工作负裁自动化

在大数据和现代 IT 环境中,任务调度与工作负载自动化(WLA)工具是优化资源利用、提升生产效率的核心驱动力。随着企业对数据分析、实时处理和多地域任务调度需求的增加,这些工具成为关键技术。本文将介绍当前技术发展背景下的Top 10开源任务调度工具,并探讨它们在大数据和工…

五分钟入门双拼!

从零开始学双拼的第一篇:概述‍这是从零开始学双拼的第一篇:概述 双拼的原理 如果你使用全拼,想要完整敲出一个字的读音,需要敲出这个字拼音的每个字母。 虽然简拼能简化一点步骤,但除非是很常见的成语、俗语,否则重码率很高,选词很困难。 有没办法提高效率呢?有的,那…

SVN提交日志模板设置

前言:每次提交时都要手动输入很多固定日志信息,或者在最近中选择信息记录会比较麻烦,通过这个设置可以在每次提交时,自动填充日志信息 设置步骤 1:先进入你想要提交svn自动设置模板时的目录(例如策划同学进入到Table表格提交记录,程序同学进入到代码提交目录,美术同学进…

ubuntu:旧版本配置apt源(ubuntu 21.10)

一,旧版本ubuntu上的apt源不能用了 # apt-get update 忽略:1 http://mirrors.aliyun.com/ubuntu hirsute InRelease 忽略:2 http://mirrors.aliyun.com/ubuntu hirsute-security InRelease 忽略:3 http://mirrors.aliyun.com/ubuntu hirsute-updates InRelease 忽略:4 http://…

医药企业数据治理,从何入手?一文讲清楚!

在医药行业,随着企业信息化进程的加速推进,ERP、CRM等系统纷纷引入业务流程。这些系统的不断增加,虽提升了业务管理的精细度,但也带来了数据的分散与冗余问题,数据治理因此成为企业面临的关键挑战。那么,医药企业的数据治理该如何入手?本文将为您逐一解析。 1. 数据标准…

【SpringBoot开发】 文件上传 (秒传、断点续传、分片上传)

原创 Java技术前沿引言 文件上传在软件开发项目中极为常见,涵盖了图片、音频、视频及各类文档的上传需求。对于小型文件,简单的Form表单上传机制通常足以应对。然而,当面对体积庞大的文件,如超过1GB的文件,或用户处于网络条件不佳的环境下时,传统的上传方式便显得力不从心…