Android中JVM七大垃圾收集器【解析】

news2024/9/20 18:34:02

概述

GC垃圾收集器的种类

  • 新生代:年轻代用来存放最近创建的对象
  • 老年代:主要存放应用程序中生命周期长的内存对象
  • 永久代:内存的永久保存区域(类和元数据),GC不参与回收
  • Serial收集器:串行收集器(单线程)
  • Serial Old:(Serial的老年代版本)
  • ParNew收集器:Serial收集器的(多线程)版本
  • Parallel Scavenge收集器:用户可控制吞吐量(多线程)
  • Parallel Old: Parallel老年代版本(多线程)
  • CMS收集器:并行标记扫描收集器(老年代、低停顿、多线程)
  • G1收集器:分代收集器,适用新生代和老年代

根据线程特点,可以将收集器分为三类:

  1. 串行收集器:Serial 收集器、Serial Old 收集器;
// 串行收集器开启方式
-XX:+UseSerialGC
  1. 并行收集器:Parallel Scavenge 收集器、Parallel Old 收集器、ParNew 收集器;
// 并行收集器开启方式
-XX:+UseSerialGC
  1. 并发收集器:CMS 收集器、G1 收集器。
// CMS 收集器开启方式
-XX:+UseParNewGC -XX:+UseConcMarkSweepGC
​
// G1 收集器开启方式
-XX:+UseG1GC

收集器介绍

serial

  • 新生代:Serial 垃圾收集器是 JVM 运行在 Client 模式下默认的新生代垃圾收集器;
  • 复制算法 :Serial 是最基本垃圾收集器,使用复制算法,曾经是 JDK1.3.1 之前新生代唯一的垃圾收集器;
  • 单线程:Serial 只会使用一个 CPU 或一条线程去完成垃圾收集工作;
  • 线程暂停:Serial 在进行垃圾收集的时,必须暂停其他所有的工作线程,直到垃圾收集结束;
  • 单线程效率最高:Serial 对于限定单个 CPU 环境来说,没有线程交互的开销,可以获得最高的单线程垃圾收集效率。

ParNew

  • 新生代:ParNew 垃圾收集器是很多 JVM 运行在 Server 模式下新生代的默认垃圾收集器;
  • 复制算法 : ParNew 和 Serial 一样使用了复制算法;
  • 多线程 :ParNew 垃圾收集器其实是 Serial 收集器的多线程版本;
  • 线程暂停:ParNew 和 Serial 一样垃圾收集的同时,必须暂停其他所有的工作线程;
  • 默认线程数:ParNew 收集器默认开启和 CPU 数目相同的线程数,可以通过-XX:ParallelGCThreads 参数来限制垃圾收集器的线程数。

Parallel Scavenge

  • 新生代:Parallel Scavenge 收集器也是一个新生代垃圾收集器;
  • 复制算法:Parallel Scavenge 收集器同样使用复制算法;
  • 多线程 :Parallel Scavenge 收集器也是一个多线程的垃圾收集器;
  • 高吞吐量:Parallel Scavenge 重点关注的是程序达到一个可控制的吞吐量(Thoughput,吞吐量 = 运行用户代码时间 / (运行用户代码时间 + 垃圾收集时间)),高吞吐量可以最高效率地利用 CPU 时间,尽快地完成程序的运算任务;
  • 适用场景:主要适用于在后台运算而不需要太多交互的任务。自适应调节策略也是 ParallelScavenge 收集器与 ParNew 收集器的一个重要区别。

新生代 Parallel Scavenge 收集器与 ParNew 收集器工作原理类似:

  1. 都是多线程的收集器;
  2. 都使用的是复制算法;
  3. 在垃圾收集过程中都需要暂停所有的工作线程。

Serial Old

  • 老年代:Serial Old 是 Serial 垃圾收集器老年代的版本;
  • 标记-整理算法:Serial Old 使用标记-整理算法;
  • 单线程:Serial Old 与 Serial 一样是单线程收集器;
  • Client 模式:JVM 运行在 Client 模式下,Serial Old 是默认的老年代垃圾收集器;
  • Server 模式:JVM 运行在 Server 模式下,Serial Old 主要有两个用途:
  1. 在 JDK1.5 之前版本中与新生代的 Parallel Scavenge 收集器搭配使用;
  2. 作为年老代中使用 CMS 收集器的后备垃圾收集方案。

新生代 Serial 与年老代 Serial Old 搭配垃圾收集过程图:

新生代 Parallel Scavenge 收集器与 ParNew 收集器工作原理类似,都是多线程的收集器,都使用的是复制算法,在垃圾收集过程中都需要暂停所有的工作线程。新生代 Parallel Scavenge/ParNew 与年老代 Serial Old 搭配垃圾收集过程图:

Parallel Old

  • 老年代:Parallel Old 收集器是 Parallel Scavenge 的老年代版本;
  • 标记-整理算法:Parallel Old 收集器使用标记-整理算法;
  • 多线程:Parallel Old 收集器是多线程收集器;
  • JDK1.6:Parallel Old 是 JDK1.6才开始提供的。

在 JDK1.6 之前,新生代使用 ParallelScavenge 收集器只能搭配年老代的 Serial Old 收集器,只能保证新生代的吞吐量优先,无法保证整体的吞吐量,Parallel Old 正是为了在年老代同样提供吞吐量优先的垃圾收集器,如果系统对吞吐量要求比较高,可以优先考虑新生代 Parallel Scavenge和年老代 Parallel Old 收集器的搭配策略。

新生代 Parallel Scavenge 和年老代 Parallel Old 收集器搭配运行过程图:

CMS

  • 老年代:CMS(Concurrent mark sweep)收集器是一种年老代垃圾收集器;
  • 标记-清理算法:和其他年老代使用标记-整理算法,CMS 使用标记-清除算法;
  • 多线程 :CMS 采用的是多线程的标记-清除算法;
  • 停顿时间端: CMS最主要目标是获取最短垃圾回收停顿时间,最短的垃圾收集停顿时间可以为交互比较高的程序提高用户体验。

CMS 运行过程分为以下 4 个阶段:

  1. 初始标记:标记 GC Roots 能直接关联的对象(速度很快,需要暂停所有的工作线程);
  2. 并发标记:进行 GC Roots 跟踪(和用户线程一起工作,不需要暂停工作线程);
  3. 重新标记:修正因用户程序继续运行而导致标记产生变动的那一部分对象的标记(需要暂停所有的工作线程);
  4. 并发清除:清除 GC Roots 不可达对象(和用户线程一起工作,不需要暂停工作线程)。

由于耗时最长的并发标记和并发清除过程中,垃圾收集线程可以和用户现在一起并发工作,所以总体上来看CMS 收集器的内存回收和用户线程是一起并发地执行。

G1

特点

  • 无分代:G1 将新生代,老年代的物理空间划分取消了。这样我们再也不用单独的空间对每个代进行设置了,不用担心每个代内存是否足够;
  • 标记-整理算法:G1 收集器采用标记-整理算法,无内存碎片产生;
  • 分区回收:G1 虽然没有了新生代与老年代的物理限制,但是 G1 采取内存分区策略,将堆内存划分为大小固定的几个独立区域。在分区中,同时存在新生代与老年代;

分区

新生代区域:G1 收集器中新生代的垃圾收集依然采用暂停所有应用线程的方式,将存活对象拷贝到老年代或者 Survivor 空间; 老年代区域:G1 收集器通过将对象从一个区域复制到另外一个区域,以此来完成老年代的清理工作; Humongous区域:巨型对象区域。如果一个对象占用的空间超过了分区容量 50% 以上,G1 收集器就认为这是一个巨型对象。这些巨型对象,默认直接会被分配在年老代,但是如果它是一个短期存在的巨型对象,就会对垃圾收集器造成负面影响。为了解决这个问题,G1 划分了一个 Humongous 区,它用来专门存放巨型对象。如果一个 H 区装不下一个巨型对象,那么 G1 会寻找连续的 H 分区来存储。为了能找到连续的 H 区,有时候不得不启动 Full GC。

对象分配策略

说起大对象的分配,我们不得不谈谈对象的分配策略。它分为3个阶段:

  1. TLAB(Thread Local Allocation Buffer)线程本地分配缓冲区
  2. Eden区中分配
  3. Humongous区分配

TLAB为线程本地分配缓冲区,它的目的为了使对象尽可能快的分配出来。如果对象在一个共享的空间中分配,我们需要采用一些同步机制来管理这些空间内的空闲空间指针。在Eden空间中,每一个线程都有一个固定的分区用于分配对象,即一个TLAB。分配对象时,线程之间不再需要进行任何的同步。

对TLAB空间中无法分配的对象,JVM会尝试在Eden空间中进行分配。如果Eden空间无法容纳该对象,就只能在老年代中进行分配空间。

最后,G1提供了两种GC模式,Young GC和Mixed GC,两种都是Stop The World(STW)的。下面我们将分别介绍一下这2种模式。

G1 Young GC

Young GC 主要是对 Eden 区进行 GC ,它在 Eden 空间耗尽时会被触发。在这种情况下,Eden 空间的数据移动到 Survivor 空间中,如果 Survivor 空间不够,Eden 空间的部分数据会直接晋升到年老代空间。Survivor 区的数据移动到新的 Survivor 区中,也有部分数据晋升到老年代空间中。最终 Eden 空间的数据为空,GC 停止工作,应用线程继续执行。

G1 Young GC 阶段:

  1. 根扫描:静态和本地对象被扫描;
  2. 更新RS: 处理 Dirty Card 队列更新 RS(Remembered Set,作用是跟踪指向某个 Heap 区内的对象引用);
  3. 处理RS: 检测从年轻代指向年老代的对象;
  4. 对象拷贝:拷贝存活的对象到 Survivor/Old 区域;
  5. 处理引用队列: 软引用,弱引用,虚引用处理。

G1 Mix GC

Mix GC不仅进行正常的新生代垃圾收集,同时也回收部分后台扫描线程标记的老年代分区。

G1 Mix GC运行步骤:

  1. 全局并发标记(global concurrent marking) 1.1. 初始标记(initial mark,STW):在此阶段,G1 GC 对根进行标记。该阶段与常规的 (STW) 年轻代垃圾回收密切相关; 1.2. 根区域扫描(root region scan):G1 GC 在初始标记的存活区扫描对老年代的引用,并标记被引用的对象。该阶段与应用程序(非 STW)同时运行,并且只有完成该阶段后,才能开始下一次 STW 年轻代垃圾回收; 1.3. 并发标记(Concurrent Marking):G1 GC 在整个堆中查找可访问的(存活的)对象。该阶段与应用程序同时运行,可以被 STW 年轻代垃圾回收中断; 1.4. 最终标记(Remark,STW): 该阶段是 STW 回收,帮助完成标记周期。G1 GC 清空 SATB 缓冲区,跟踪未被访问的存活对象,并执行引用处理; 1.5. 清除垃圾(Cleanup,STW):在这个最后阶段,G1 GC 执行统计和 RSet 净化的 STW 操作。在统计期间,G1 GC 会识别完全空闲的区域和可供进行混合垃圾回收的区域。清理阶段在将空白区域重置并返回到空闲列表时为部分并发。
  2. 拷贝存活对象(evacuation)

G1 收集器与 CMS 收集器相比,G1 收集器两个最突出的改进是:

  1. 基于标记-整理算法,不产生内存碎片;
  2. 可以非常精确控制停顿时间,在不牺牲吞吐量前提下,实现低停顿垃圾回收。
// G1 收集器参数设置
-XX:+UseG1GC -Xmx32g -XX:MaxGCPauseMillis=200
// -XX:+UseG1GC —— 为开启G1垃圾收集器,
// -Xmx32g —— 设计堆内存的最大内存为32G,
// -XX:MaxGCPauseMillis=200 —— 设置GC的最大暂停时间为200ms

以上就是Android开发中的JVM垃圾收集器的七大常用介绍;更多Android开发技术进阶,各位可以参考《Android核心技术手册》电子文档。里面的技术分为几十个小文档。包含的很全面,需要可以点击获取方法。

文末

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

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

相关文章

web网页设计—— 中国餐饮协会(HTML+CSS)

🎀 精彩专栏推荐👇🏻👇🏻👇🏻 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 💂 作者主页: 【主页——🚀获取更多优质源码】 🎓 web前端期末大作业…

CentOS8使用阿里云yum源异常问题及解决方法

镜像下载、域名解析、时间同步请点击 阿里云开源镜像站 Linux安装git时发生如下错误 [rootraoyuuuu maven]# dnf install git Repository extras is listed more than once in the configuration Repository epel is listed more than once in the configuration CentOS-8 - B…

关于windows的文件监控管理系统(Java)

目 录 摘 要 I Abstract II 1.绪论 1 1.1课题背景 1 1.2系统开发的目的和意义 2 1.3国内外概况 3 1.4研究主要内容 3 2.windows文件监控管理系统相关技术介绍 4 2.1 API 4 2.2 API HOOK 5 2.3 Java 5 2.4 DLL 6 2.4 Windows系统的Socket编程 6 2.4.1使用WinSock API 6 2.4.2 使…

【 C++ 】IO流

目录 1、C语言的输入输出 2、流是什么 3、CIO流 3.1、C标准IO流 3.2、C文件IO流 文件操作步骤 以二进制的形式操作文件 以文本的形式操作文件 4、stringstream的介绍 1、C语言的输入输出 C语言中我们用到的最频繁的输入输出方式就是scanf()和printf()。 scanf()&#xff1a…

[前端基础] JavaScript 基础篇(下)

DOM 和 BOM DOM 指的是文档对象模型,它指的是把文档当做一个对象来对待,这个对象主要定义了处理网页内容的方法和接口。BOM 指的是浏览器对象模型,它指的是把浏览器当做一个对象来对待,这个对象主要定义了与浏览器进行交互的法和…

Node核心模块之Stream

Node.js诞生之初就是为了提高IO性能,文件操作系统和网络模块实现了流接口,Node.js中流就是处理流式数据的抽象接口。 那么应用程序为什么使用流来处理数据? 常见问题 同步读取资源文件,用户需要等待数据读取完成资源文件最终一次…

【Windows】windows10时间显示秒数

一般情况下windows10的电脑时间只显示小时和分钟,但是有的用户想要时间显示更加精细,那么windows10时间怎么显示秒呢?大家可以通过修改注册表的方式进行设置:打开注册表编辑器,定位到Advanced,右键新建DWOR…

【第十四篇】Camunda系列-多人会签【多实例】

多人会签 Multiple Instance 也叫多实例任务。 1.会签说明 多实例活动是为业务流程中的某个步骤定义重复的一种方式。在编程概念中,多实例与 for each 结构相匹配:它允许对给定集合中的每个项目按顺序或并行地执行某个步骤或甚至一个完整的子流程。 多实例是一个有额外属性…

注解(Annotation)

注解 注解也被称为元数据(MateDate),用于修饰或解释包,类,方法,属性,构造器,局部变量等数据信息和注释一样,注解不会影响程序逻辑,但是注解可以被编译或者运行&#xff…

如何定义需求优先级?

本文将围绕以下问题展开:1、什么是需求优先级排序,目的是什么?2、优先级排序的8大依据;3、需求优先级排序面临的挑战;4、一些优秀的需求优先级排序工具。 一、什么是需求优先级排序,目的是什么?…

Mybatis-plus 用法

本文主要介绍 mybatis-plus 这款插件,针对 springboot 用户。包括引入,配置,使用,以及扩展等常用的方面做一个汇总整理,尽量包含大家常用的场景内容。 关于 mybatis-plus 是什么,不多做介绍了,看…

大一作业HTML网页作业:简单的旅游 1页 (旅游主题)

⛵ 源码获取 文末联系 ✈ Web前端开发技术 描述 网页设计题材,DIVCSS 布局制作,HTMLCSS网页设计期末课程大作业 | 游景点介绍 | 旅游风景区 | 家乡介绍 | 等网站的设计与制作 | HTML期末大学生网页设计作业,Web大学生网页 HTML:结构 CSS&…

94-98-Hadoop-MapReduce工作流程(重要)

Hadoop-MapReduce工作流程(重要): 上面的流程是整个 MapReduce 最全工作流程,但是 Shuffle 过程只是从第 7 步开始到第 16 步结束,具体 Shuffle 过程详解,如下: (1)Map…

Java 动态判断数组维数并取值

一、背景 技术交流群里有同学提了一个看似基础但挺有意思的问题。 问题描述: 一个对象是一个未知的数组类型,可能是 short 二维数组,可能是 int 的三维数组等。 诉求: 想要遍历修改(获取)它的值不想写太多…

springboot 接入 logback.xml 彻底搞出一个超级完整加注释的版本-可在生产环境直接使用

目录 介绍 开搞 先logback.xml相关的 pom.xml application.yml 配置 启动配置 类中编写 引入 Slf4j logback.xml 重点介绍 logback项目名称 最大保存时间 365天 lOGGER PATTERN 根据个人喜好选择匹配 控制台输出 滚动文件 过滤器 可以选择自己要的日志级别 不选…

【机器学习数据集制作】视频转图片(代码注释,思路推导)

目录数据集效果资源下载实现思路代码实战总结『机器学习』分享机器学习0基础的数据集制作过程。 欢迎关注 『机器学习』 系列,持续更新中 欢迎关注 『机器学习』 系列,持续更新中 数据集效果 资源下载 拿来即用,所见即所得。 项目仓库&#…

​LabVIEW从另一个VI或通过VI服务器访问正在运行的可执行文件

​LabVIEW从另一个VI或通过VI服务器访问正在运行的可执行文件 有没有办法从另一个VI或可执行文件访问正在运行的LabVIEW可执行文件。例如,从显示控件获取值,为控件设置值,以及初始化运行LabVIEW可执行文件VI的前面板。 在正在运行的可执行文…

IOS逆向初探

前言 这些文章用于记录学习路上的点点滴滴,也希望能给到刚入门的小伙伴们一点帮助。爱而所向,不负所心。 环境 iphone 6 MacOS Monterey 12.3.1 一、IOS开发语言 Objective-C Objective-C是iOS操作系统运用的软件开发语言。Objective-C的流行完全是因…

免费下载word简历模板的网站

我这里分享了6个免费简历网站,分享给各位。 1.OfficePlus 微软官方出品的 office 免费模板网站https://www.officeplus.cn/ 2.简历设计网 2000Word模板免费下载,每个用于每天可下载10篇免费模板。https://www.jianlisheji.com/ 3.办公资源…

mysql 一对多查询 合并为一行数据

用户包含多个角色 执行: SELECT ur.user_id,u.name user_name,u.mail,ur.role_id,r.name role_name FROM tb_user_role ur LEFT JOIN tb_user u ON u.idur.user_id LEFT JOIN tb_role r ON r.idur.role_id WHERE u.is_delete0 ORDER BY …