Java虚拟机垃圾收集器详细总结

1、Serial收集器

        Serial收集器是最基础、历史最悠久的收集器,曾经(在JDK 1.3.1之前)是HotSpot虚拟机新生代收集器的唯一选择。这个收集器是一个单线程工作的收集器,但它的“单线 程”的意义并不仅仅是说明它只会使用一个处理器或一条收集线程去完成垃圾收集工作,更重要的是强 调在它进行垃圾收集时,必须暂停其他所有工作线程,直到它收集结束。“Stop The World”这个词语也 许听起来很酷,但这项工作是由虚拟机在后台自动发起和自动完成的,在用户不可知、不可控的情况 下把用户的正常工作的线程全部停掉,这对很多应用来说都是不能接受的。

2、ParNew收集器

        ParNew收集器实质上是Serial收集器的多线程并行版本,除了同时使用多条线程进行垃圾收集之外,其余的行为包括Serial收集器可用的所有控制参数(例如:-XX:SurvivorRatio、-XX: PretenureSizeThreshold、-XX:HandlePromotionFailure等)、收集算法、Stop The World、对象分配规 则、回收策略等都与Serial收集器完全一致。

         ParNew收集器除了支持多线程并行收集之外,其他与Serial收集器相比并没有太多创新之处,但它却是不少运行在服务端模式下的HotSpot虚拟机,尤其是JDK 7之前的遗留系统中首选的新生代收集 器,其中有一个与功能、性能无关但其实很重要的原因是:除了Serial收集器外,目前只有它能与CMS 收集器配合工作。

        ParNew收集器在单核心处理器的环境中绝对不会有比Serial收集器更好的效果,甚至由于存在线程交互的开销,该收集器在通过超线程(Hyper-Threading)技术实现的伪双核处理器环境中都不能百分 之百保证超越Serial收集器。当然,随着可以被使用的处理器核心数量的增加,ParNew对于垃圾收集时 系统资源的高效利用还是很有好处的。它默认开启的收集线程数与处理器核心数量相同,在处理器核心非常多(譬如32个,现在CPU都是多核加超线程设计,服务器达到或超过32个逻辑核心的情况非常普遍)的环境中,可以使用-XX:ParallelGCThreads参数来限制垃圾收集的线程数。

3、Para lel Scavenge收集器

        Parallel Scavenge收集器也是一款新生代收集器,它同样是基于标记-复制算法实现的收集器,也是能够并行收集的多线程收集器。

        Parallel Scavenge收集器的特点是它的关注点与其他收集器不同,CMS等收集器的关注点是尽可能 地缩短垃圾收集时用户线程的停顿时间,而Parallel Scavenge收集器的目标则是达到一个可控制的吞吐量(Throughput)。所谓吞吐量就是处理器用于运行用户代码的时间与处理器总消耗时间的比值。

         如果虚拟机完成某个任务,用户代码加上垃圾收集总共耗费了100分钟,其中垃圾收集花掉1分钟,那吞吐量就是99%。停顿时间越短就越适合需要与用户交互或需要保证服务响应质量的程序,良好的响应速度能提升用户体验;而高吞吐量则可以最高效率地利用处理器资源,尽快完成程序的运任务,主要适合在后台运算而不需要太多交互的分析任务。  

        Parallel Scavenge收集器提供了两个参数用于精确控制吞吐量,分别是控制最大垃圾收集停顿时间的-XX:MaxGCPauseMillis参数以及直接设置吞吐量大小的-XX:GCTimeRatio参数。      

4、Serial Old收集器

        Serial Old是Serial收集器的老年代版本,它同样是一个单线程收集器,使用标记-整理算法。这个收集器的主要意义也是供客户端模式下的HotSpot虚拟机使用。如果在服务端模式下,它也可能有两种用 途:一种是在JDK 5以及之前的版本中与Parallel Scavenge收集器搭配使用,另外一种就是作为CMS 收集器发生失败时的后备预案,在并发收集发生Concurrent Mode Failure时使用。

5、Paralel Old收集器

        Parallel Old是Parallel Scavenge收集器的老年代版本,支持多线程并发收集,基于标记-整理算法实现。这个收集器是直到JDK 6时才开始提供的,在此之前,新生代的Parallel Scavenge收集器一直处于相当尴尬的状态,原因是如果新生代选择了Parallel Scavenge收集器,老年代除了Serial Old(PS MarkSweep)收集器以外别无选择,其他表现良好的老年代收集器,如CMS无法与它配合工作。

        直到Parallel Old收集器出现后,“吞吐量优先”收集器终于有了比较名副其实的搭配组合,在注重吞吐量或者处理器资源较为稀缺的场合,都可以优先考虑Parallel Scavenge加Parallel Old收集器这个组合。        

6、CMS收集器

        CMS(Concurrent Mark Sweep)收集器是一种以获取最短回收停顿时间为目标的收集器。

        从名字(包含“Mark Sweep”)上就可以看出CMS收集器是基于标记-清除算法实现的,它的运作 过程相对于前面几种收集器来说要更复杂一些,整个过程分为四个步骤,包括:

        (1)初始标记(CMS initial mark)

        (2)并发标记(CMS concurrent mark)

        (3)重新标记(CMS remark)

        (4)并发清除(CMS concurrent sweep)

        其中初始标记重新标记这两个步骤仍然需要“Stop The World”。初始标记仅仅只是标记一下GC Roots能直接关联到的对象,速度很快;并发标记阶段就是从GC Roots的直接关联对象开始遍历整个对象图的过程,这个过程耗时较长但是不需要停顿用户线程,可以与垃圾收集线程一起并发运行;而重新标记阶段则是为了修正并发标记期间,因用户程序继续运作而导致标记产生变动的那一部分对象的标记记录,这个阶段的停顿时间通常会比初始标记阶段稍长一 些,但也远比并发标记阶段的时间短;最后是并发清除阶段,清理删除掉标记阶段判断的已经死亡的 对象,由于不需要移动存活对象,所以这个阶段也是可以与用户线程同时并发的。

        由于在整个过程中耗时最长并发标记并发清除阶段中,垃圾收集器线程都可以与用户线程一 起工作,所以从总体上来说,CMS收集器的内存回收过程是与用户线程一起并发执行的。

 缺点:

  1. CMS收集器对处理器资源非常敏感。在并发阶段,它虽然不会导致用户线程停顿,但却会因为占用了一部分线程(或者说处理器的计 算能力)而导致应用程序变慢,降低总吞吐量。
  2. CMS收集器无法处理“浮动垃圾”(Floating Garbage),有可能出现“Con-current Mode Failure”失败进而导致另一次完全“Stop The World”的Full GC的产生。在CMS的并发标记和并发清理阶 段,用户线程是还在继续运行的,程序在运行自然就还会伴随有新的垃圾对象不断产生,但这一部分 垃圾对象是出现在标记过程结束以后,CMS无法在当次收集中处理掉它们,只好留待下一次垃圾收集时再清理掉。这一部分垃圾就称为“浮动垃圾”。
  3. 收集结束时会有大量空间碎片产生。CMS是一款基于“标记-清除”算法实现的收集器。

7、Garbage First收集器

        Garbage First(简称G1)收集器开创了收集器面向局部收集的设计思路基于Region的内存布局形式

        G1是一款主要面向服务端应用的垃圾收集器。在G1收集器出现之前的所有其他收集器,包括CMS在内,垃圾收集的目标范围要么是整个新生代(Minor GC),要么就是整个老年代(Major GC),再要么就是整个Java堆(Full GC)。而G1跳出了这个樊笼,它可以面向堆内存任何部分来组成回收集(Collection Set,一般简称CSet)进行回收,衡量标准不再是它属于哪个分代,而 是哪块内存中存放的垃圾数量最多,回收收益最大,这就是G1收集器的Mixed GC模式

        G1开创的基于Region的堆内存布局是它能够实现这个目标的关键。虽然G1也仍是遵循分代收集理论设计的,但其堆内存的布局与其他收集器有非常明显的差异:G1不再坚持固定大小以及固定数量的 分代区域划分,而是把连续的Java堆划分为多个大小相等的独立区域(Region),每一个Region都可以根据需要,扮演新生代的Eden空间、Survivor空间,或者老年代空间

        Region中还有一类特殊的Humongous区域,专门用来存储大对象。G1认为只要大小超过了一个 Region容量一半的对象即可判定为大对象。

,G1收集器的 运作过程大致可划分为以下四个步骤:

  1. 初始标记(Initial Marking):仅仅只是标记一下GC Roots能直接关联到的对象,并且修改TAMS 指针的值,让下一阶段用户线程并发运行时,能正确地在可用的Region中分配新对象。这个阶段需要 停顿线程,但耗时很短,而且是借用进行Minor GC的时候同步完成的,所以G1收集器在这个阶段实际 并没有额外的停顿。
  2. 并发标记(Concurrent Marking):从GC Root开始对堆中对象进行可达性分析,递归扫描整个堆里的对象图,找出要回收的对象,这阶段耗时较长,但可与用户程序并发执行。当对象图扫描完成以后,还要重新处理SATB记录下的在并发时有引用变动的对象
  3. 最终标记(Final Marking):对用户线程做另一个短暂的暂停,用于处理并发阶段结束后仍遗留 下来的最后那少量的SATB(原始快照)记录。
  4. 筛选回收(Live Data Counting and Evacuation):负责更新Region的统计数据,对各个Region的回收价值和成本进行排序,根据用户所期望的停顿时间来制定回收计划,可以自由选择任意多个Region 构成回收集,然后把决定回收的那一部分Region的存活对象复制到空的Region中,再清理掉整个旧 Region的全部空间。这里的操作涉及存活对象的移动,是必须暂停用户线程,由多条收集器线程并行完成的。

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

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

相关文章

自制贪吃蛇小游戏

此片文章涉及到到控制台设置的相关操作,虚拟键码,宽字符输出等,有些地方大家可能会看不懂,可以阅读以下文章来进一步了解: 控制台程序设置-CSDN博客 效果展示: QQ2024428-181932 源码已放在文章结尾 目录 …

Vivado-IP-DDS and Testbench Learning

DDS内部结构 实现流程 首先新建一个工程,创建bd文件,添加DDS Compiler核,此处不多赘述 Block Design 在观测输出的信号时,需要将最高位符号位的信号取反,这样才能输出正弦波,否则输出的波形如下图所示 将t…

Strassen矩阵乘法——C++

【题目描述】 根据课本“Strassen矩阵乘法”的基本原理,设计并实现一个矩阵快速乘法的工具。并演示至少10000维的矩阵快速乘法对比样例。 【功能要求】 实现普通矩阵乘法算法和“Strassen矩阵乘法”算法对相同的矩阵,分别用普通矩阵乘法算法&#xff…

C语言:数据结构(单链表)

目录 1. 链表的概念及结构2. 实现单链表3. 链表的分类 1. 链表的概念及结构 概念:链表是一种物理存储结构上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表的指针链接次序实现的。 链表的结构跟火车车厢相似,淡季时车次的车厢会相应…

ULTIMATE VOCAL REMOVER V5 for Mac:专业人声消除软件

ULTIMATE VOCAL REMOVER V5 for Mac是一款专为Mac用户设计的人声消除软件,它凭借强大的功能和卓越的性能,在音乐制作和后期处理领域崭露头角。 ULTIMATE VOCAL REMOVER V5 for Mac v5.6激活版下载 这款软件基于深度神经网络,通过先进的训练模…

Windows使用bat远程操作Linux并执行命令

背景:让客户可以简单在Windows中能自己执行 Linux中的脚本,傻瓜式操作! 方法:做一个简单的bat脚本!能远程连接到Linux,并执行Linux命令!客户双击就能使用! 1、原先上网查询到使用P…

hadoop命令

hadoop命令 目录 hadoop命令 1.查看文件下面有哪些文件和目录 2.获取文件信息 查看文件内容 3.创建一个文件夹 4.剪切 1)从本地hadoop剪切到hdfs并上传到hdfs 2)剪切 从hdfs剪切到本地hadoop目录上 5.删除 1)递归删除 2&#xff0…

AI Agent新对决:LangGraph与AutoGen的技术角力

AI Agent变革未来,LangGraph对抗AutoGen ©作者|Blaze 来源|神州问学 引言 比尔.盖茨曾在他的博客上发表一篇文章:《AI is about to completely change how you use computers》。在文章中,比尔盖茨探讨AI Agent对我们未来生活的巨大影…

windows电脑改造为linux

有个大学用的旧笔记本电脑没啥用了,决定把它改成linux搭一个服务器; 一、linux安装盘制作 首先要有一个大于8G的U盘,然后去下载需要的linux系统镜像,我下的是ubuntu,这里自选版本 https://cn.ubuntu.com/download/d…

请求响应案例-员工管理系统

准备工作 1、在pom.xml文件中引入dom4j依赖&#xff0c;解析xml文件。如果该依赖爆红&#xff0c;那么刷新以下就可以。 <!-- 解析XML --><dependency><groupId>org.dom4j</groupId><artifactId>dom4j</artifactId><version>2.1.3…

自然语言处理: 第三十章Hugging face使用指南之——trainer

原文连接: Trainer (huggingface.co) 最近在用HF的transformer库自己做训练&#xff0c;所以用着了transformers.Trainer&#xff0c;这里记录下用法 基本参数 class transformers.Trainer( model: Union None,args: TrainingArguments None,data_collator: Optional Non…

debian和ubuntu的核心系统和系统命令的区别

Debian和Ubuntu虽然有很深的渊源&#xff0c;都是基于Debian的发行版&#xff0c;但它们在核心系统和系统命令上还是有一些差别的。以下是一些主要的不同之处&#xff1a; 1. 发布周期&#xff1a; - Debian&#xff1a; Debian项目采用滚动发布模型&#xff0c;持续更新&a…

[论文笔记]GAUSSIAN ERROR LINEAR UNITS (GELUS)

引言 今天来看一下GELU的原始论文。 作者提出了GELU(Gaussian Error Linear Unit,高斯误差线性单元)非线性激活函数&#xff1a; GELU x Φ ( x ) \text{GELU} x\Phi(x) GELUxΦ(x)&#xff0c;其中 Φ ( x ) \Phi(x) Φ(x)​是标准高斯累积分布函数。与ReLU激活函数通过输入…

Python 爬虫如何配置代理 IP (Py 采集)

在Python中配置代理IP&#xff0c;可以通过设置requests库的proxies参数来实现。以下是一个示例&#xff1a; import requests# 则立可以获取稳定代理Ip&#xff1a;https://www.kuaidaili.com/?refrg3jlsko0ymg # 推荐使用私密动态 IP proxies {"http": "ht…

以太网交换机自学习与转发帧

自学习算法:每次转发帧前先将当前MAC地址以及对应的接口好存入到帧交换表中

ios CI/CD 持续集成 组件化专题一 iOS 将图片打包成bundle

一、 创建 选择 macos 下的Bundle 二 、取名点击下一步 三、Base SDK 选择ios 四 、Build Active Architecture Only 五、Installation后面的内容删除 六、Skip Install 选择NO 七、Strip Debug Symbols During Copy 中"Release"项设置为 "YES" 八、COM…

区块链基础——区块链应用架构概览

目录 区块链应用架构概览&#xff1a; 1、区块链技术回顾 1.1、以太坊结点结构 1.2、多种应用场景 2、区块链应用架构概览 2.1、传统的Web2 应用程序架构 2.2、Web3 应用程序架构——最简架构 2.3、Web3 应用程序架构——前端web3.js ether.js 2.4、Web3 应用程序架构—…

Android Widget开发代码示例详细说明

因为AppWidgetProvider扩展自BroadcastReceiver, 所以你不能保证回调函数完成调用后&#xff0c;AppWidgetProvider还在继续运行。 a. AppWidgetProvider 的实现 /*** Copyright(C):教育电子有限公司 * Project Name: NineSync* Filename: SynWidgetProvider.java * Author(S…

逆向案例三十——webpack登录某游戏

网址&#xff1a;aHR0cHM6Ly93d3cuZ205OS5jb20v 步骤&#xff1a; 进行抓包分析&#xff0c;找到登录接口&#xff0c;发现密码有加密 跟栈分析&#xff0c;从第三个栈进入&#xff0c;打上断点&#xff0c;再次点击登录 明显找到password,它由o赋值&#xff0c;o由a.encode(…

gitee / github 配置git, 实现免密码登录

文章目录 怎么配置公钥和私钥验证配置成功问题 怎么配置公钥和私钥 以下内容参考自 github ssh 配置&#xff0c;gitee的配置也是一样的&#xff1b; 粘贴以下文本&#xff0c;将示例中使用的电子邮件替换为 GitHub 电子邮件地址。 ssh-keygen -t ed25519 -C "your_emai…