我的编程空间,编程开发者的网络收藏夹
学习永远不晚

JVM垃圾回收——G1垃圾收集器

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

JVM垃圾回收——G1垃圾收集器

目录

一、什么是G1垃圾收集器

二、G1垃圾收集器的内存划分

三、G1垃圾收集器的收集过程

 四、G1收集器的优缺点

五、G1收集器的JVM参数配置


一、什么是G1垃圾收集器

        Garbage First(简称G1)收集器是垃圾收集器技术发展史上里程碑式的成果,它摒弃了传统垃圾收集器的严格的内存划分,而是采用局部回收的设计思路和基于Region的内存布局形式。

        G1是一款主要面向服务端应用的垃圾收集器,在jdk6 update14时,就有了实验版本。而到了jdk7 update4之后移除了“Experimental”标识。它的目的是为了适应现在不断扩大的内存和不断增加的处理器数量,进一步降低暂停时间(pause time),同时兼顾良好的吞吐量。如今已经完全替代CMS垃圾收集器,CMS收集器在JDK9 中被废弃,在JDK 14中被移除。

二、G1垃圾收集器的内存划分

         从上面图上可以看到,G1垃圾收集器也是基于分代收集理论设计的,但是它的堆内存的布局与其他垃圾收集器的布局有很明显的区别,G1收集器不再按照固定大小以及固定数量的分代区域划分,而是把JAVA堆划分为2048个大小相等的独立的Region,每个Region大小可以通过参数-XX:G1HeapRegionSize设定,取值范围为1-32MB,且必须为2的N次幂。每一个Region都可以根据需要充当新生代的Eden区、S0和S1区或者老年代。在一般的垃圾收集中对于堆中的大对象,默认直接会被分配到老年代,但是如果它是一个短期存在的大对象,就会对垃圾收集器造成负面影响。为了解决这个问题,G1划分了一个Humongous区,它用来专门存放大对象。如果一个H区装不下一个大对象,那么G1会寻找连续的H区来存储。为了能找到连续的H区,有时候不得不启动Full GC。 G1的大多数行为都把H区作为老年代的一部分来看待。当一个对象的大小超过了一个Region容量的一半,即被认为是大对象。

        虽然G1仍然保留新生代和老年代的概念,但新生代和老年代不再是固定的了,而是一系列区域(不需要连续,逻辑连续即可)的动态集合。由于G1这种基于Region回收的方式,可以预测停顿时间。G1会根据每个Region里面垃圾“价值”的大小,在后台维护一个优先级列表,每次根据用户设定的允许收集停顿的时间(-XX:MaxGCPauseMillis,默认为200毫秒)优先处理价值收益最大的Region。

三、G1垃圾收集器的收集过程

在了解G1收集过程之前,我们首先考虑几个问题

1、将java堆分成多个独立的Region后,Region里面存在的跨Region引用的对象是如何解决的?

答:G1收集器和其他垃圾收集器模型一样,存在跨代引用的解决方法是使用记忆集(Remembered Set)具体细节可以参考本人的另一篇博文中的跨代引用JVM垃圾回收——垃圾回收的一些细节实现_熟透的蜗牛的博客-CSDN博客

使用记忆集避免了全堆作为GC Roots扫描,但实际上G1收集器为每一个Region都维护了自己的记忆集,这些记忆集会记录下其他的Region指向自己的指针,并标记这些指针分别在那些卡页范围之内。G1的记忆集在存储结构的本质上是一种哈希表,key是其他Region的起始地址,value是卡表索引号的集合。这种双向卡表的结构比原来的卡表实现更复杂,也正是因为这种双向卡表和多Region的之间的引用导致G1收集器比其他收集器占用的内存要多。根据经验G1至少占用JAVA堆容量的10%-20%额外内存来维护收集器的工作。

2、G1是一个并发标记的收集器,那么在并发回收阶段,G1如果解决“漏标”的情况?如何解决在回收过程中重新分配到该Region上的新对象不被回收的?

答:G1是如何解决存活对象被标记成垃圾对象的,CMS收集器采用增量更新算法实现,G1收集器是通过原始快照(SATB)算法来实现的,具体细节可以参考本人的这篇博文JVM垃圾回收——三色标记法_jvm 三色标记_熟透的蜗牛的博客-CSDN博客

        G1是一款并发回收的垃圾收集器,那么垃圾在回收时程序还继续运行,只要程序运行就会持续有新对象创建。G1为每个Region设计了两个名为TAMS(Top At Mark Start )的指针,把Region中的一部分空间划分出来,用于存储并发回收阶段新分配的对象,并发回收时新分配的对象的地址都必须在这两个指针位置以上,G1默认这个指针位置以上的对象都是隐式标记过的,默认他们是存活对象,不纳入本次回收的范围。与CMS中的“Concurrent Mode Failure”失败会导致Full GC 类似,如果回收速度赶不上分配速度,那么G1也要被迫冻结用户线程,进行Full GC而产生长时间的Stop The World。

3、G1如何建立可靠的停顿模型?

答:用户使用-XX:MaxGCPauseMills参数指定停顿时间,这个时间只是期望值,而不是说指定了200毫秒,就会在200毫秒内将垃圾回收完毕。G1收集器的停顿模型是以衰减均值为理论基础来实现的。在垃圾收集过程中,G1会记录每个Region的回收耗时,记忆集中脏卡数量等各个步骤的花费成本,然后统计出平均值,标准偏差、置信度等统计信息。然后可以计算回收那些Region,可以在期望的时间内达到最大的收益。

 初始标记:仅仅只是标记一下GC Roots能直接关联到的对象,并且修改TAMS指针的值,让下一阶段用户线程并发运行时,能够在Region上正确的分配对象。这个阶段需要STW,耗时很短,而且是借用MinorGC(上一轮垃圾回收时触发GC)时候同步完成的。

并发标记:从GC Roots 开始对堆中的对象进行可达性分析,递归扫描整个堆里的对象,这个过程耗时较长,但是是与用户线程并发执行的。对象扫描完之后还需要重新处理STAB记录下的在并发时有引用变动的对象。

最终标记:这个阶段也需要STW,用于处理并发阶段结束后仍然遗留下来的最后少量的STAB记录。

筛选回收:负责更新Region的统计数据,对各个Region的回收价值和成本排序,根据用户期望的停顿时间来执行回收计划,然后把决定回收的Region里的存活对象复制到空的Region,然后清空旧Region的空间。由于涉及到对象的移动,所以这个阶段也是需要STW的。

从上述可以看出,除了并发标记,其他阶段都是需要STW的,G1收集器不单单是追求低延迟的收集器,也衡量了吞吐量,所以在延迟和吞吐量之间做了一个权衡。

 四、G1收集器的优缺点

G1收集器一直都拿来和CMS垃圾收集器作比较,这里也用CMS垃圾收集器作对比。

  • 优势:因为CMS是基于标记-清除的算法实现的,所以CMS会有空间碎片化的问题。而在G1收集器上是不存在的,G1从整体上来看是基于标记-整理算法实现,从Region之间又是基于标记-复制算法实现的。
  • 由于G1不会产生空间碎片,可以为对象的分配提供更规整的内存。此外还避免了由于分配大对象时找不到连续的内存空间,而不得不提前触发下一次垃圾回收。
  • 不足:由于跨Region引用等大量双向卡表的存在,G1收集器比CMS(只需要处理老年代到新生代的引用)占用更多的内存。
  • CMS收集器使用写后屏障来更新维护卡表,而G1收集器除了使用写后屏障维护卡表,为了实现SATB的算法,还需要使用写前屏障来跟踪并发时指针变化情况。所以G1收集器会增加程序运行时的额外负载。

五、G1收集器的JVM参数配置

  • -XX:+UseG1GC  手动指定使用G1收集器执行内存回收任务(JDK9后不用设置,默认就是G1)。
  • -XX:G1HeapRegionSize  设置每个Region的大小。值是2的幂,范围是1MB到32MB之间,目标是根据最小的Java堆大小划分出约2048个区域。默认是堆内存的1/2000。
  • -XX:MaxGCPauseMillis  设置期望达到的最大GC停顿时间指标(JVM会尽力实现,但不保证达到)。默认值是200ms(如果这个值设置很小,如20ms,那么它收集的region会少,这样长时间后,堆内存会满。产生FullGC,FullGC会出现STW,反而影响用户体验)。
  • -XX:G1NewSizePercent  新生代的最小值默认是5%,此参数在实验阶段,如果想使用加-XX:+UnlockExperimentalVMOptions参数。
  • -XX:G1MaxNewSizePercent 新生代的最大值,默认值是60%,此参数在实验阶段,如果想使用加-XX:+UnlockExperimentalVMOptions参数。
  • -XX:ParallelGCThreads 设置STW时GC线程数的值。最多设置为8(垃圾回收线程)。
  • -XX:ConcGCThreads 设置并发标记的线程数。将n设置为并行垃圾回收线程数(ParallelGCThreads)的1/4左右。
  • -XX:InitiatingHeapOccupancyPercent  设置触发并发GC周期的Java堆占用率阈值。超过此值,就触发GC。默认值是45%。

测试代码

package com.wssnail.test;import java.util.ArrayList;import java.util.List;public class TestG1 {    private static String[] strArr = new String[]{"中国人民万岁", "梅西好样的,梅西好样的梅西好样的梅西好样的梅西好样的梅西好样的梅西好样的梅西好样的", "我爱看世界杯,我爱看世界杯我爱看世界杯我爱看世界杯我爱看世界杯我爱看世界杯我爱看世界杯我爱看世界杯我爱看世界杯"};    public static void main(String[] args) {        List list = new ArrayList<>();        for (int i = 0; i < 100000; i++) {            try {                Thread.sleep(200);            } catch (InterruptedException e) {                e.printStackTrace();            }            list.add(strArr);        }        while (true) {        }    }}

JVM参数如下

-XX:+UseG1GC-Xlog:gc*-XX:G1HeapRegionSize=1-XX:MaxGCPauseMillis=250-XX:+UnlockExperimentalVMOptions-XX:G1NewSizePercent=5-XX:G1MaxNewSizePercent=60-XX:ParallelGCThreads=2-XX:+PrintCommandLineFlags

来源地址:https://blog.csdn.net/weixin_39555954/article/details/128022143

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

JVM垃圾回收——G1垃圾收集器

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Java11 的 G1 垃圾收集器

作为 5 年以上工作经验的技术人员,或多或少在系统维护,系统保障,系统调优遇到过上面的这几个场景,你可能是通过重启,调整一些JVM参数解决,如果大家需要深入的探究找到问题的原因,可以耐心看看下文我对 G1 的一些总结。
Java11G12024-11-30

JVM 垃圾回收算法和 CMS 垃圾回收器

本文核心主要是讲述:JVM 中的几种垃圾回收算法理论,以及多种垃圾收集器,并且详细参数 CMS 垃圾收集器的实现、优缺点等,最后也会解释一下三色标记法与读写屏障。

详解JVM 的垃圾回收算法和垃圾回收器

为了让这部分动态的内存分配能够进行合理的回收,就需要垃圾回收算法和垃圾回收器来帮忙了。下面让我们进入今天的主题。

JVM分代垃圾回收机制和垃圾回收算法

在C/C++中,我们需要用到内存的时候,需要先手动申明一下,使用完后又需要在手动回收一下,这两部非常麻烦而且还经常会出这个方面的问题。而这一切在Java中就已经被自动执行掉了,所以我们写代码的时候都不用再管这些无效的数据。
JVM回收算法2024-12-02

JVM垃圾回收器详解

这篇文章主要介绍“JVM垃圾回收器详解”,在日常操作中,相信很多人在JVM垃圾回收器详解问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”JVM垃圾回收器详解”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!1
2023-06-02

JVM垃圾回收器是什么

这篇文章主要讲解了“JVM垃圾回收器是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“JVM垃圾回收器是什么”吧!并发与并行并行(Parallel):并行描述的是多条垃圾收集器线程之间的关
2023-07-02

JVM垃圾回收器有哪些

这篇文章主要介绍“JVM垃圾回收器有哪些”,在日常操作中,相信很多人在JVM垃圾回收器有哪些问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”JVM垃圾回收器有哪些”的疑惑有所帮助!接下来,请跟着小编一起来学习吧
2023-06-05

JVM调优之垃圾定位、垃圾回收算法、垃圾处理器对比

谈垃圾回收器之前,要先讲讲垃圾回收算法,以及JVM对垃圾的认定策略,JVM垃圾回收器是垃圾回收算法的具体实现,了解了前面的前置知识,有利于对垃圾回收器的理解。

垃圾回收你懂,Java垃圾回收你懂吗?

在用 C 之类的编程语言时,程序员需要自己手动分配和释放内存。而 Java 不一样,它有垃圾回收器,释放内存由回收器负责。本文接下来将介绍Java垃圾收集的知识原理。

JVM基本垃圾回收算法

这篇文章主要介绍“JVM基本垃圾回收算法”,在日常操作中,相信很多人在JVM基本垃圾回收算法问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”JVM基本垃圾回收算法”的疑惑有所帮助!接下来,请跟着小编一起来学习吧
2023-06-17

深入浅出JVM垃圾回收器

本文对Java虚拟机垃圾回收器及其回收策略进行逐一介绍,同时对垃圾回收的优化思路做一些简单讨论,以期读者能对Java虚拟机的垃圾回收增加理解,同时对垃圾回收的优化有一些初步认识,为后续工作中的Java应用调优打下基础。

JVM优化:垃圾回收概述

“虚引用”顾名思义,它是最弱的一种引用关系。如果一个对象仅持有虚引用,在任何时候都可能被垃圾回收器回 收。虚引用主要用来跟踪对象被垃圾回收器回收的活动。

JVM常见垃圾收集器有哪些

这篇文章主要介绍了JVM常见垃圾收集器有哪些的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇JVM常见垃圾收集器有哪些文章都会有所收获,下面我们一起来看看吧。垃圾收集器类型垃圾收集器 是 垃圾收集算法 的具体实现
2023-07-02

有哪些jvm垃圾回收算法

这篇文章将为大家详细讲解有关有哪些jvm垃圾回收算法,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。jvm垃圾回收算法:1、“标记–清除”算法;首先标记出所有需要被回收的对象,然后在标记完成后
2023-06-14

JVM 垃圾回收的工作原理

本文讨论了各种不同的 JVM 内存“代”,以及它们是如何在分代垃圾回收算法中起作用的。对于程序员来说,掌握 Java 的内存管理机制并不是必须的,但它能够帮助你更好地理解 JVM 处理程序中的变量和类实例的方式。

JVM系列:MinorGC、MajorGC、FullGC垃圾回收

从年轻代空间(包括 Eden 和 Survivor 区域)回收内存被称为 Minor GC,也叫Young GC。因为Java对象大多具备朝生夕死的特征,所以MinorGC非常频繁,一般回收速度也比较快。一般采用复制算法。​

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录