jvm之G1 GC

news/2024/11/24 13:27:47/

写在前面

jdk9以及之后的版本已经将默认的垃圾收集器parallel更换为G1.本文就一起来看下。

1:G1介绍

parallel GC的设计目标是高吞吐量,CMS GC的设计目标是低延迟,而G1的设计目标不是这二者中的任何一个,其设计目标是让GC的STW时间变的可控和可配置,具体的实现方案是将内存划分为多个region,默认是2048个,每个region可能是old区,eden区,也可能是survivor区,并且随着程序的运行可能会随时发生转变,如下图:

在这里插入图片描述

每次GC时会处理所有的年轻代(eden region和survivor region),以及部分的老年代,这些需要垃圾回收的region叫做回收集(collection set),如下图打对号的:
在这里插入图片描述

2:G1重要参数

  • -XX:+UseG1GC
    启用G1 GC
  • -XX:G1NewSizePercent
    初始年轻代占用整个堆的百分比,默认时5%
  • -XX:G1MaxNewSizePercent
    年轻代占用堆最大的百分比,默认是60%
  • -XX:G1HeapRegionSize
    设置region的大小,单位是MB,需要设置为2的次幂值,当大对象无法分配时可以适当将该值调大
  • -XX:ConcGCThreads
    与Java应用一起执行的GC线程数量,该值越低则系统的吞吐量越大,但过低会导致GC时间过长
  • -XX:InitiatingHeapOccupancyPercent
    当老年代垃圾达到指定百分比时,开始老年代的并行回收。即该值决定了什么时候启动老年代GC,默认时45%
  • -XX:G1HeapWastePercent
    当垃圾占用百分比达到多少时,停止GC,默认是5%,即每次GC并不会回收所有的垃圾对象,部分垃圾对象会留到之后的GC进行回收
  • -XX:GCTimeRatio
    设置GC占用的CPU时间和工作线程占用CPU时间的比例,计算公式100/(1+GCTimeRatio),G1默认值为9,则10%的时间会用在GC上,parallel默认值是99,则1%的时间会用在GC上
  • -XX:MaxGCPauseMillis
    设置每次GC的暂停时间,单位毫秒,G1会尽量维持在这个时间,但不保证绝对是,即如果设置50ms,最终GC时间100,200ms都是有可能的

3:G1的不足

当在某些情况下G1触发了FULL GC,将会退化为serial GC使用单线程的方式来进行垃圾回收,可能发生原因以及处理办法如下。

3.1:老年代被填满

这种情况一般是因为参与GC的线程数过少,无法快速的进行垃圾回收,导致老年代填满,解决办法是通过参数-XX:ConcGCThreads调大参与GC的线程数

3.2:巨型对象分配失败

对象过大,无法找到一个可用的region,则会触发FULL GC,解决办法是通过参数-XX:G1HeapRegionSize调大region的大小,或者是增加整个堆内存大小,从而间接增大单个region的大小

4:G1参数配置

测试使用的jar从这里 下载。

首先使用G1相关的配置启动程序,如下:

bogon:~ xb$ java -version
java version "9.0.4"
Java(TM) SE Runtime Environment (build 9.0.4+11)
Java HotSpot(TM) 64-Bit Server VM (build 9.0.4+11, mixed mode)bogon:temp xb$ java -Xmx1g -Xms1g -XX:+UseG1GC -XX:-UseAdaptiveSizePolicy -XX:MaxGCPauseMillis=200 -jar gateway-server-0.0.1-SNAPSHOT.jar .   ____          _            __ _ _/\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \\\/  ___)| |_)| | | | | || (_| |  ) ) ) )'  |____| .__|_| |_|_| |_\__, | / / / /=========|_|==============|___/=/_/_/_/:: Spring Boot ::        (v2.0.4.RELEASE)

查看堆快照:

bogon:temp xb$ jps -l
1939 jdk.jcmd/sun.tools.jps.Jps
1576 gateway-server-0.0.1-SNAPSHOT.jarbogon:temp xb$ jhsdb jmap --heap --pid 1576
Attaching to process ID 1576, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 9.0.4+11using thread-local object allocation.
Garbage-First (G1) GC with 4 thread(s) -- 使用G1 GC,4个GC线程Heap Configuration:MinHeapFreeRatio         = 40MaxHeapFreeRatio         = 70MaxHeapSize              = 1073741824 (1024.0MB) -- 最大堆内存大小NewSize                  = 1363144 (1.2999954223632812MB) -- 新生代初始大小1MMaxNewSize               = 643825664 (614.0MB) -- 新生代最大大小614mOldSize                  = 5452592 (5.1999969482421875MB) 初始old区大小5mNewRatio                 = 2 young:old=1:2SurvivorRatio            = 8 eden:s0:s1=8:1:1MetaspaceSize            = 21807104 (20.796875MB)CompressedClassSpaceSize = 1073741824 (1024.0MB)MaxMetaspaceSize         = 17592186044415 MB -- 最大metaspace无限大,天文数字,即不限制G1HeapRegionSize         = 1048576 (1.0MB)  -- 每个region的大小1m,没有设置是默认大小Heap Usage:
G1 Heap: -- 堆配置(young+Old)regions  = 1024 -- 一共1024个region,每个regsion 1m,所以总大小为1gcapacity = 1073741824 (1024.0MB) -- 总大小1gused     = 47431216 (45.23393249511719MB) -- 已使用堆大小45mfree     = 1026310608 (978.7660675048828MB) -- 空闲堆大小978m4.417376220226288% used -- 使用量为4.4%
G1 Young Generation: -- 堆内存年轻代配置
Eden Space: -- young的edenregions  = 23 -- 一共23个regioncapacity = 53477376 (51.0MB) -- 容量是51mused     = 24117248 (23.0MB) -- 使用了23mfree     = 29360128 (28.0MB) -- 空闲28m45.09803921568628% used -- 使用率为45%
Survivor Space: -- 存活区regions  = 4 -- 一共4个regioncapacity = 4194304 (4.0MB) -- 总大小4mused     = 4194304 (4.0MB) -- 已使用4mfree     = 0 (0.0MB) -- 空闲0m100.0% used -- 使用率100%
G1 Old Generation: -- 堆内存老年代regions  = 19 -- 一共19个regioncapacity = 39845888 (38.0MB) -- 总容量38mused     = 19119664 (18.233932495117188MB) -- 已使用约18mfree     = 20726224 (19.766067504882812MB) -- 空暇约19m47.98403288188734% used -- 使用率约48%22285 interned Strings occupying 2350032 bytes.

写在后面


http://www.ppmy.cn/news/75203.html

相关文章

用数据讲故事:十大统计学/机器学习魔法指数

统计学和机器学习为数据分析提供理论基础,入门时我看过很多统计学相关书籍,复杂的公式和推导过程让我一度陷入迷茫。对于数据科学/分析师来说,如何使用统计学知识并应用到我们的分析场景中更为重要。本文主要基于数据分析工作中的实际应用场景…

rust cargo工具常用插件列表

插件功能安装命令advisory检查 Cargo 依赖项中是否存在安全漏洞。cargo install cargo-advisoryasm生成 Rust 代码的汇编版本。cargo install cargo-asmaudit搜索 Rust 代码及其依赖项中的安全漏洞并输出警告。cargo install cargo-auditbenchcmp比较 Rust 基准测试结果。cargo…

(1分钟速览)g2o入门指南--笔记版

在slam后端中,优化的框架很多,有ceres,g2o,gtsam这些。要想真正掌握slam后端的优化内容,这些框架是必不可少的上手练习的内容。本文则介绍有关g2o的相关内容,作为一个入门指南,目标:…

【重新定义matlab强大系列七】利用matlab函数ischange查找数据变化点

🔗 运行环境:matlab 🚩 撰写作者:左手の明天 🥇 精选专栏:《python》 🔥 推荐专栏:《算法研究》 #### 防伪水印——左手の明天 #### 💗 大家好🤗&#x1f91…

可视区域兼容性问题的思考及方法封装

今日在复习可视化尺寸获取时突发奇想,为什么要在怪异模式下使用document.body.clientWidth,在标准模式下使用document.documentElement.clientWidth?以及是否在IE8及以下的版本中其中一个获取方式将返回undefined或0。  出于该问题的思考&am…

Java字节流battle字符流

目录 Java字节流(Byte Stream) FileInputStream和FileOutputStream Java字符流(Character Stream) FileReader和FileWriter 如何在使用是区分什么时候用输出什么时候用输入 Write方法 close方法 Java中的close方法本身抛出…

用docker搭建Ceph集群(基于nautilus版本)

用docker搭建Ceph集群(基于nautilus版本) 在本文中,我们将使用Docker搭建Ceph集群。我们将使用nautilus版本,这是Ceph的最新长期支持版本。 步骤1:安装Docker 首先,我们需要安装Docker。可以在Docker官网…

【 计算机组成原理 】第七章 外围设备

系列文章目录 第一章 计算系统概论 第二章 运算方法和运算器 第三章 多层次的存储器 第四章 指令系统 第五章 中央处理器 第六章 总线系统 第七章 外围设备 第八章 输入输出系统 文章目录 系列文章目录前言第七章 外围设备7.1 外围设备概述7.1.1 外围设备的一般功能7.1.2 外围…