G1垃圾回收器
垃圾回收器的发展历程
背景
01、G1
解决的问题
G1
垃圾回收器是04
年正式提出,12
开始正式支持,在17
年作为JDK9
默认的垃圾处理器。
在04
年的时候,java
程序堆的内存越来越大,从而导致程序中可存活的活对象越来越多,因此GC
的STW
时间越来越长。这是G1
要解决的主要问题:STW
带来的停顿时间太长了。
CMS
在此之前效率也很高,但活对象数量一多,STW
时间也很长。而且CMS
无法解决内存碎片化的问题。
G1
还解决的问题是:CMS
在GC
后,无法compact
内存。
02、G1
达成的目标
(1)减少由于STW
而带来的程序延迟时间,做到伪实时、低延时、可设定目标;
可设定目标是指能够设置GC
最大STW
停顿的时间,G1
会尽量达成目的,但不一定达成。
-XX:MaxGCPauseMillis=N
默认情况下是250毫秒
(2)解决CMS
在GC
后,无法压缩程序内存的问题;
(3)在JDK9
之后,默认的垃圾处理器就是G1
;它适用于堆内存较大的情况下(>4~6G
);
G1
垃圾回收器
一、G1
内存布局
G1
不再遵循之前的堆中对象的分代排列,而是将堆分成若干个等大的区域。
而是变成:
默认是分成
2048
个区域,-XX:G1HeapRegionSize=N 2048
Humongous
:当你分配的一个对象超过一半区域的大小时,这个对象就会被放入这个区域。这个区域属于老年代区域。
二、G1
的介绍
G1
垃圾回收器不再回收整个堆,而是选择一个Collection Set
(CS
)。而且每次GC
时,会估计每个Region
中的垃圾比例,优先回收垃圾多的Region
。这就为什么被叫做Garbage First
算法。这也是为什么G1
可以控制STW
停顿时间的原因。
G1
含有三种GC
算法:
Full young GC
:年轻代GC
算法:STW
、Parallel
、Copying
- 老年代
GC
算法:Mostly-concurrent marking
、Incremental compaction
Mixed GC
:混合GC
三、G1
引来的问题
问题描述
G1
将年轻代、老年代区域划分为许多个小区域,增加在GC
判断对象是否为垃圾的难度。比如:
- 老年代对象可能持有年代代的引用(跨代引用)
- 不同的
Region
间的互相引用
假设在Full young GC
时,某个年轻代Region
对象可能被老年代的某个对象引用,那么我在回收这个年轻代Region
时,怎么知道这里面的对象是否被其他Region
、老年代引用呢?
问题解决
Remembered Set
、Card Table
1、CardTable
每个Region
中分为很多区域,每个区域我们成为CardTable
,对应的就是上述蓝色区域;每个CardTable
有多个entry
组成。当对应的内存空间发生改变时,就会标记为dirty
。
2、RememberedSet
当Region1
的CardTable
引用Region2
的CardTable
时,Region2
的RememberedSet
就会记录对应CardTable
中的entry
,可以根据其找到对应的内存区域。
3、解析
当某个内存对应进行赋值是,就是对象的set
方法,我们可以在这种方法上添加dirty
的描述。
这其实就是典型的时间换空间的做法:用额外的空间维护引用信息,这就是占用5~10%
的过多内存占用。
解决方法的实现
1、Write Barrier
介绍
Write barrier
是一种向JVM
注入的一小段代码,用于记录指针变化。比如说object.field = <reference>
。
在JVM
开始更新指针时,就经过以下几步:
- 标记
Card
为Dirty
- 将
Card
存入Dirty Card Queue
队列中
这里有一个问题:为什么要放在队列里,而不是直接去更新RememberedSet
呢?
这是因为JVM
运行可能会有多个线程并行的修改RememberedSet
,这样就需要花费额外的时间来解决多线程同步问题。而这种更新引用是频繁的,所以这种额外时间是无法忍受的。
2、Dirty Card Queue
这个队列有白、绿、黄、红四个颜色,表示应用线程往这个队列放任务的状态。
White
表示没有应用线程往队列里放任务,什么事都不用干。Green
此时Refinement
线程开始被激活,开始更新RS
。-XX:G1ConcRefinementGreenZone=N
Yellow
此时全部的Refinement
线程都被激活,来更新RS
。-XX:G1ConcRefinementYellowZone=N
Red
这个时候,应用线程也开始参与排空队列的工作。-XX:G1ConcRefinementRedZone=N
四、GC
算法的过程
1、Fully young GC
GC
的过程
(1)STW
此时会暂停所有堆中的对象,将部分Region
拷贝到指定区域。
(2)构建Collection Set
fully young GC
就是选取所有的Eden
和Survivor
。
(3)扫描GC Roots
(4)更新RememberedSet
排空Dirty Card Queue
(5)Process RS
根据RS
找到要GC
的对象被哪些对象引用了。
(6)对象拷贝
survivor
区域对象的调整。
(7)Reference Processing
额外会做的事
G1
记录每个阶段的时间,用于后期自动调优。比如说会记录Eden
、Survivor
的数量和GC
时间,后期会根据我们之前设定的暂停目标来自动调整Region
数量。
但是我们设置暂停目标越短,年轻代的Region
数量就越少。但这可能会导致Fully young GC
频繁发生。
2、Old GC
当堆用量达到一定程度时,就会触发old GC
。可以通过以下参数进行设置:
-XX:InitatingHeapOccpancyPercent=45
old GC
有一个很大特点就是并发进行的。但它是如何在堆中不断变化的情况下,确定哪些是要清理的垃圾对象呢?
三色标记算法
这种算法实现了在不暂停应用线程的情况下进行并发标记,标记过程过如下:
(1)将GC Root
对象记录为黑色,其直接引用对象记录为灰色,并将这些灰色对象放入一个队列中
(2)从队列取出对象,将其标为黑色,将其引用对象记录为灰色,再放入队列中
(3)直到队列中无对象为止
三色标记算法的缺点:Lost Object Problem
三色标记算法并没有完全将所有的活对象都标记出来,这就是Lost Object Problem
问题。比如说:
(1)刚开始时
(2)在即将描述将C
标为灰色的一刹那
此时,C
依然是活对象,但是已经无法将其标记了。
(3)结果
Lost Object Problem
的解决
这种解决办法还是通过Write barrier
技术来解决。当B.c=null
,也就是C
指针被删除时,G1
还是被认为活对象。
那如果
C
是新生对象呢?这是老年代GC
Old GC
过程
(1)STW
老年代GC
会在这个时候,进行一次Fully young GC
(2)恢复应用线程
(3)使用三色标记算法并发标记(init marking
)
(4)STW
这时候会有一个Remark
阶段,主要是解决SATB
、Reference processing
还会有一个Cleanup
阶段,用于回收全为空的区
(5)恢复应用线程
3、Mixed GC
我们直到CMS
最大的缺点就是无法进行压缩操作,而G1
就通过Mixed GC
解决了这个问题。
Mixed GC
没有固定触发条件,他是根据Fully young GC
收集的信息和我们配置的时间来决定,是否触发Mixed GC
。它会根据暂停目标,来优先选择垃圾最多的Old Region
来执行。
Mixed GC
会选择若干个Region
进行,默认是选择1/8
的Old Region
、Eden Region
、Survivor Region
。
Mixed GC
的过程跟Fully young GC
的过程相同,都是:STW
、Parallel
、Copying
。
G1垃圾回收器的更多相关文章
- 深入浅出具有划时代意义的G1垃圾回收器
G1诞生的背景 Garbage First(简称G1)收集器是垃圾收集器技术发展历史上的里程碑式的成果,它开创了收集器面向局部收集的设计思路和基于Region的内存布局形式.HotSpot开发团队最初 ...
- JVM学习——G1垃圾回收器(学习过程)
JVM学习--G1垃圾回收器 把这个跨时代的垃圾回收器的笔记独立出来. 新生代:适用复制算法 老年代:适用标记清除.标记整理算法 二娃本来看G1的时候觉得比较枯燥,但是后来总结完之后告诉我说,一定要慢 ...
- G1垃圾回收器在并发场景调优
一.序言 目前企业级主流使用的Java版本是8,垃圾回收器支持手动修改为G1,G1垃圾回收器是Java 11的默认设置,因此G1垃圾回收器可以用很长时间,现阶段垃圾回收器优化意味着针对G1垃圾回收器优 ...
- G1 垃圾回收器简单调优
G1: Garbage First 低延迟.服务侧分代垃圾回收器. 详细介绍参见:JVM之G1收集器,这里不再赘述. 关于调优目标:延迟.吞吐量 一.延迟,单次的延迟 单次的延迟关系到服务的响应时延, ...
- 探索G1垃圾回收器
前言 最近王子因为个人原因有些忙碌,导致文章更新比较慢,希望大家理解,之后也会持续和小伙伴们一起共同分享技术干货. 上篇JVM的文章中我们对ParNew和CMS垃圾回收器已经有了一个比较透彻的认识,感 ...
- JAVA之G1垃圾回收器
概述 G1 GC,全称Garbage-First Garbage Collector,通过-XX:+UseG1GC参数来启用,作为体验版随着JDK 6u14版本面世,在JDK 7u4版本发行时被正式推 ...
- jvm默认的并行垃圾回收器和G1垃圾回收器性能对比
http://www.importnew.com/13827.html 参数如下: JAVA_OPTS="-server -Xms1024m -Xmx1024m -Xss256k -XX:M ...
- G1垃圾回收器参数配置
下面是完整的 G1 的 GC 开关参数列表. 选项/默认值 说明 -XX:+UseG1GC 使用 G1 (Garbage First) 垃圾收集器 -XX:MaxGCPauseMillis=n 设置最 ...
- JVM七大垃圾回收器下篇G1(Garbage First)
G1回收器:区域化分代式 既然我们已经有了前面几个强大的GC,为什么还要发布Garbage First (G1)GC? 原因就在于应用程序所应对的业务越来越庞大.复杂,用户越来越多,没有GC就不能保 ...
随机推荐
- vue 带参数的跳转-完成一个功能之后 之后需要深思,否则还会忘记
我要写详细点,否则下次很容易忘记 写了一个页面,这个页面里面添加了 很多a 标签,跳转都是同一个页面,内容不一样,方法 首先 路由 设定好 routes:[ { path:'/aaa', name:' ...
- PHP8年开发经验原创开发文档教程
订阅微信公众号: gzgwgas 每天为你分享PHP开发经验,坚决不踩坑,坚决不入坑. 微信扫码,关注公众号有惊喜!
- Drf(DjangoRestFramewok)
第一部分 问题 1.前后端分离? vue.js 后端给前段返回json数据 2.移动端盛行. app 后端给app返回json数据 3.PC端应用? crm项目,前段后端一起写,运行在浏览器上. 一般 ...
- (转)C++ 虚函数表解析
原文地址:http://blog.csdn.net/haoel/article/details/1948051 C++ 虚函数表解析 陈皓 http://blog.csdn.net/haoel 前言 ...
- NIO中的ZeroCopy
前文提到网络IO可以使用多路复用技术,而文件IO无法使用多路复用,但是文件IO可以通过减少底层数据拷贝的次数来提升性能,而这个减少底层数据拷贝次数的技术,就叫做ZeroCopy. 操作系统层面的Zer ...
- appium移动自动化详解
1移动自动化简介 移动自动化就是通过代码来控制手机,模拟人的动作,对手机进行一些点击,输入等操作,那python代码如何能控制到手机呢?目前的思路应该是python代码->Appium-pyth ...
- golang超级mapper包 - coven
coven介绍 你可以把它理解成.NET 的 AutoMapper,java的modelmapper 一个快速的转换器去,支持结构到结构,切片到切片和映射到映射非反射转换,类型与嵌套指针支持. 不支持 ...
- AAAI 2020 | DIoU和CIoU:IoU在目标检测中的正确打开方式
论文提出了IoU-based的DIoU loss和CIoU loss,以及建议使用DIoU-NMS替换经典的NMS方法,充分地利用IoU的特性进行优化.并且方法能够简单地迁移到现有的算法中带来性能的提 ...
- Python第六章-函数01-函数的概念和使用
函数 为了便于程序的维护和更好的实现模块化,好的程序都会分解为很多函数. 可以这么说,对于任何的编程语言,函数都是一个非常重要的概念. python 不仅简化了函数的定义过程,而且还大量借鉴了其他函数 ...
- 【笔记3-31】Python语言基础-元组tuple
创建元组 my_tuple = () my_tuple1 = 1, 2, 3, 4, 5, 6 元组解包 与元组元素数量一致 a,s,d,f,g,h = my_tuple1 a, b, c, *f = ...