把这个跨时代的垃圾回收器的笔记独立出来。
新生代:适用复制算法
老年代:适用标记清除、标记整理算法
二娃本来看G1的时候觉得比较枯燥,但是后来总结完之后告诉我说,一定要慢慢的学,不要跳过东西。之前不懂的在后面总结的时候就豁然开朗了。
G1从JDK9开始,已经成为默认垃圾收集器。
垃圾优先的收集器和其他收集器最明显的不通:
物理结构和形态和之前极为不同。比如对于堆的使用空间的划分。哪里用于老年代,哪里用于新生代等等。
鱼和熊掌可兼得
吞吐量关注的是在一个指定的时间内,最大化一个应用的工作量
TPS:在同一个小时内同一个事物(或者任务,请求)完成的次数
数据库一小时可以完成多少次查询。
对于关注吞吐量的系统来说,卡顿(STW)是可以接受的。
指一个程序或者系统对请求能够及时相应。如
对于这类对相应能力敏感的场景,长时间的停顿是无法接受的。
G1就是为了解决这两种问题而存在的垃圾回收器。(设计目标)
满足短时间GC停顿的同时达到一个较高的吞吐量
使用JVM参数就可以启用G1垃圾回收器。
几乎不需要STW,但是还有的。 一般很多人喜欢拿G1和CMS比较。
GC停顿更加可控(和新的物理结构设计有很大的关系,堆的内存的划分方式和CMS不一样。不是按照新生代和老年代来划分堆内存的。)
浮动垃圾:在清除的过程中,还会有产生的垃圾。这些垃圾称为浮动垃圾。
G1的设计规划:是要替换掉CMS。
但是实际上,并不是为了替换而替换的。因为不同的业务系统对于不同的需求不一样。必须对响应能力要求比较高的情况下,有时候是不需要考虑吞吐量的,所以在选用的时候还是需要酌情考虑。
HotSpot虚拟机的主要构成
方法区:存储的类的元数据,全局性的信息等等
Heap:堆,存放对象
Java线程:
程序计数器:用来表示程序指令所持有的信息
Naive:本地内部线程
再往下:执行引擎:JIT Compiler 及时编译器,垃圾收集器
年轻代:Eden,S0,S1。 复制算法。
Old Generation:老年代。
永久代:已经弃用。1.8 包括1.8 以后就没有了。 老年代是不会晋升永久代的。永久代存的是常量之类的东西。 (10年以上工作经验的 好多都会说错,说老年代晋升永久代)
描述:交织在一起,没有规律可言。
显然:命名策略没有发生变化,还是用的Eden、Survivor、Old Generation、作用还是原来的作用。
但是:物理内存的方式,发生了翻天覆地的变化,和传统的堆内存划分没什么关系。
G1:堆内存,就是一个区域,就是一个Heap。regions
对每个角色的数量并没有强制的限定,对每种内存的大小,可以动态变化。
G1最大的特点就是高效的执行回收,优先去执行那些大量对象可回收的区域(region)。
G1采用复制算法
G1只是特定的整理几个Region。并不是整理所有的Region。所以GC停顿时间会明显变少。
关于G1的一些重要概念
分区:G1是依附的重要概念。每一个区域的大小是一样的。但是角色会动态发生变化。但是在同一时刻,某一个分区只是属于单一的某一个代。
年轻代,幸存区,老年代这些概念还在,但是成为了逻辑上的概念。
G1名字由来:垃圾优先。 G1会优先回收垃圾对象特别多的分区。
G1:在新生代满的时候,对新生代进行回收。和传统的一致。
复制算法的优点
CSet:就是要被收集的区域的集合。统称为收集集合。
RSet:记录其他Region中对象的引用本Region中对象的关系。
价值在于:不需要扫描整个堆去找谁引用了当前分区中的对象。只需要扫描Rset即可。
上述内容摘自:知乎 R大, RednaxelaFX.
4个重要概念:
SATB
Region
CSet
RSet
https://www.oracle.com/technetwork/tutorials/tutorials-1876574.html
![image-20200221055615144](/Users/shangyifeng/Library/Application Support/typora-user-images/image-20200221055615144.png)
三个跟性能有关的JVM组件。高亮了。调优的时候主要针对这三部分。
两种调优:1. 调整堆的大小 2. 选择合适的垃圾回收器。 3. 在新版本的JDK中,我们几乎不用动JIT。
关于:关注点响应能力和吞吐量 的解释原文。
关于G1存在的目的:是为了替换CMS。和G1的详细介绍。
我去,这些东西不是都在官网吗?
When performing garbage collections, G1 operates in a manner similar to the CMS collector. G1 performs a concurrent global marking phase to determine the liveness of objects throughout the heap. After the mark phase completes, G1 knows which regions are mostly empty. It collects in these regions first, which usually yields a large amount of free space. This is why this method of garbage collection is called Garbage-First. As the name suggests, G1 concentrates its collection and compaction activity on the areas of the heap that are likely to be full of reclaimable objects, that is, garbage. G1 uses a pause prediction model to meet a user-defined pause time target and selects the number of regions to collect based on the specified pause time target.
The regions identified by G1 as ripe for reclamation are garbage collected using evacuation. G1 copies objects from one or more regions of the heap to a single region on the heap, and in the process both compacts and frees up memory. This evacuation is performed in parallel on multi-processors, to decrease pause times and increase throughput. Thus, with each garbage collection, G1 continuously works to reduce fragmentation, working within the user defined pause times. This is beyond the capability of both the previous methods. CMS (Concurrent Mark Sweep ) garbage collector does not do compaction. ParallelOld garbage collection performs only whole-heap compaction, which results in considerable pause times.
It is important to note that G1 is not a real-time collector. It meets the set pause time target with high probability but not absolute certainty. Based on data from previous collections, G1 does an estimate of how many regions can be collected within the user specified target time. Thus, the collector has a reasonably accurate model of the cost of collecting the regions, and it uses this model to determine which and how many regions to collect while staying within the pause time target.
Note: G1 has both concurrent (runs along with application threads, e.g., refinement, marking, cleanup) and parallel (multi-threaded, e.g., stop the world) phases. Full garbage collections are still single threaded, but if tuned properly your applications should avoid full GCs.
RSet和CSet的概念
G1收集器的阶段:
和CMS阶段执行内容不同的阶段。
G1总结:
有问题,就查询官网。
Young GC和 Mix GC
Eden空间满的时候,收集新生代。使用G1收集器。
CSet
RSet涉及两个概念:points-into 和 points-out
SATB三色算法:增量式的标记算法。:沿着某一个起点,逐步的深入追踪。这就叫增量式。
我们不能将本来不是垃圾的对象当成垃圾来回收的,这种情况百分百是不能出现的。
把本来是垃圾的对象,认为不是垃圾。这种情况是允许的。称为浮动垃圾。
对于G1的收集,两种模式:对于年轻代的收集成为Young GC。 Mixed GC对于老年代和年轻代,都能够回收。
全局并发标记:
Young GC触发时间:
那么 什么时候触发Mixed GC?
G1HeapWasterPercent:参数
G1MixedGCLiveThresholdPercent:参数
G1MixedGCCOuntTarget:参数
G1OldSetRegionThresholdPercent:参数
G1 GC其他参数
其中:humongous为超大空间
无论是新生代还是老年代,都是复制算法。
巨大对象:存放在humongous区域。如果一个H区域放不下,会寻找连续的H分区来存储。
三色标记算法为了解决并行标记出问题的情况。(漏标-本来不是垃圾的对象没有标记)(误标-本来是垃圾的没有标记)
并发标记采用的算法:三色标记算法。描述:追踪式(从根部追踪)。
但凡被标记对象,都不是垃圾,都不应该没回收掉
黑色:根对象,GCRoot,起源/ 该对象或者子对象都被扫描过了,也是黑色。
灰色:还没标记完,扫描当中
白色:还未被标记。扫描完成之后,白色对象就是不可达的对象,即垃圾对象。
变黑:是因为 不再引用其他的任何对象了,自身也扫描完了。
垃圾回收的漏标问题是如何产生的呢?如下状态
如果A.c = C。 B.c = null. 变成了这个样子。
这时候的问题就是:C对象已经被漏掉了。要被回收掉了。显然这是不合理的。这就是漏标现象。
变成非白色的:变成非白色之后就不会被垃圾回收掉了。就算真的没用了,也没事。但是就是不能被误删除。
新生代用分区,并不是为了提升效率。只是为了适合能够控制大小
隐式标记:默认灰色。找到新分配的对象
完整标记的流程
手动通过用户设置为null的,标记灰色
这里的停顿时间,并不是越短越好。因为:时间短,收集的垃圾就少。
不断调优暂停时间指标:-XX:MaxGCPauseMillis=x
暂停时间不能太短:如果太短就会导致出现G1跟不上垃圾产生的速度。最终退化成FUll GC。
不要设置新生代和老年代的大小
G1有自动调大小的功能
关注Evacuation Failure
通过上面的初次学习,应该对G1有了很好的认识。
以上都是概念性的描述。
概念肯定是要知道的。然后再实践。针对底层原理要精读,慢啃。
对于JVM的学习,不要东一棒槌,西一榔头的。全面的涉及。
记录记录记录,学习的时候记住了,之后肯定会忘记
学习没有任何捷径。研读源码。网上的文章一般都是到底层的时候,就结束了。
openjdk.java.net
看别人,是偷懒的表现,能够让自己不用经过大脑思考,不经过自己的努力就能够获取到,而往往也不珍惜。
2020年02月23日11:16:24
关于JVM的学习暂时先到这里。
手机扫一扫
移动阅读更方便
你可能感兴趣的文章