JVM总结(二):垃圾回收器
这一节我们来总结一下JVM垃圾收集器方面的东西。
垃圾回收器
判断对象引用是否失效
对象生存判断算法
- 引用计数法
给对象中添加一个引用计数器,每当一个地方引用到这个对象的时候,计数器值就加1,当引用失效时,计数器的值就减1,当计数器值变为0时,便说明该对象不可能再被使用了。
优点:实现简单,判定效率较高。
缺点:当出现对象之间的相互循环引用时,即两个类中都存在引用字段分别引用着对方的时候,在回收过程中这时该算法无效。 - 可达性分析算法
为了克服引用计数法的弊端,现在比较主流的实现算法是可达性分析算法。该算法的基本思想是通过一系列的成为“GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链。如果在一次的搜索中,一个对象到GC Roots没有任何的引用链相连,则说明此对象是不可用的。具体如图所示
GC Roots的判定:
1、虚拟机栈(栈帧中的本地变量表)中引用的对象
2、方法区中静态属性引用的对象
3、方法区中常量引用的对象
4、本地方法栈中JNI(即一般说的Native方法)引用的对象
引用判断过程
判断引用是否无效的过程分为三个阶段
1、当JVM进行垃圾收集时,JVM使用可达性分析算法进行分析,如果对象在进行可达性分析后发现没有与GC Roots相连接的引用链,此时该对象将被第一次标记,并进行一次筛选,筛选的条件是此对象有没有必要执行finalize()方法,如果对象没有覆盖该方法,或者该方法已经被虚拟机调用过了,虚拟机将这两种情况都视为“没有必要执行”。
2、如果该对象被判定为有必要执行finalize()方法,那么对象将会被放置到一个叫做F-Queue的队列中,并在稍后由一个由虚拟机自动建立的、低优先级的Finalizer线程去执行它。这里所谓的执行是指虚拟机会触发这个方法,但并不承若会等待它运行结束。因为一个对象可能在finalize()方法中执行缓慢,或者发生了死循环,这将导致该队列中的其他对象长期处于等待阶段,甚至导致整个内存系统的奔溃。
3、F-Queue中的标记筛选。
finalize()方法是对象逃脱死亡命运的最后一次机会,然后GC将对F-Queue中的对象进行第二次小规模的标记。如果对象在finalize()方法中成功拯救了自己,即与引用链上的任何一个对象建立关联,那么在第二次标记的时候,该算法将被移出F-Queue的集合,如果对象这个时候还没有逃脱,那基本上它就真的被回收了。
垃圾收集算法简介
目前比较主流的垃圾收集算法有四种:标记-清除算法、复制算法、标记-整理算法、分代收集算法。具体分析对比如下:
| 分类 | 标记-清除算法(Mark-Sweep) | 复制算法(Coping) | 标志-整理算法(Mark-Compact) | 分代收集算法(Generational Collection) |
|---|---|---|---|---|
| 进行整理 | 否 | 是 | 是 | 是 |
| 算法实现过程 | 该算法分为两个过程:标记和清除。先标记出所有需要回收的对象,在标记完成后统一回收所有被标记的要回收的对象。 | 将内存按容量划分为大小相等的两块区域,每次使用其中的一块,当一块的内存用完了,执行GC算法时将还存活的对象整理复制到另外一块上,然后清理所有的内存块。 | 该算法分为两个过程:标记和整理。首先标记出所有需要回收的对象,然后让存活的对象都向内存的一端移动,然后直接清除掉端边界以外的内存。 | 根据对象存活周期的不同将内存划分为几块,一般是划分为新生代和老年代,然后根据各个年代的特点采用不同的最适当的收集算法。 |
| 优点 | 简单,易于实现 | 内存分配时算法不产生内存碎片 | 内存分配时算法不产生内存碎片,也比较易于实现 | 分代收集,效率较高 |
| 缺点 | 1、效率低 2、会产生大量不连续的内存碎片 | 空间消耗太大,内存被压缩为原来的一半 | 算法复杂度大,执行步骤较多 | 算法复杂度大,执行步骤较多 |
垃圾收集器
常见的JVM垃圾收集器有七种,具体如下图所示:
新生代垃圾收集器
- Serial
Serial收集器是单线程的一个收集器,但它的单线程的意义是它只会使用一个CPU或者一条收集线程去完成垃圾收集工作,更重要的是在它进行垃圾收集的时候,必须暂停其他所有的工作线程,直到它收集结束。
分代收集算法:新生代单线程采用复制算法,并暂停所有用户线程;老年代单线程采用标记-整理算法,并暂停所有用户线程。 - ParNew
ParNew收集器是Serial收集器的多线程版。其基本操作和Serial算法基本一致。该收集器一般搭配CMS收集器进行工作。‘
分代收集算法:新生代采用复制算法,并暂停所有用户线程;老年代采用标记-整理算法,并暂停所有用户线程。 - Parallel Scavenge
Parallel Scavenge收集器是也与ParNew算法十分相似,但是与其他收集器的关注点大多是尽可能缩短垃圾收集时用户线程的停顿时间,而Parallel Scavenge收集器目的是达到一个可控制的吞吐量。吞吐量就是CPU用于运行用户代码的时间与CPU总消耗的时间的比值。即吞吐量=运行用户代码时间/(运行用户代码时间+垃圾收集时间),举个例子,虚拟机总共运行了100分钟,其中垃圾收集花掉1分钟,那吞吐量就是99%。
GC自适应调节策略:JVM会根据当前系统的运行情况收集性能监控信息,动态调整这些参数以提供最合适的停顿时间或者最大吞吐量。Parallel Scavenge收集器可以搭配自适应调节策略。
分代收集算法:新生代采用复制算法,并暂停所有用户线程;老年代采用标记-整理算法,并暂停所有用户线程。
老年代垃圾收集器
- Serial Old
Serial Old是Serial算法的老年代版本,同样是一个单线程收集器。该收集器主要是给Client模式下的虚拟机使用的。
分代收集算法:新生代单线程采用复制算法,并暂停所有用户线程;老年代单线程采用标记-整理算法,并暂停所有用户线程。 - Parallnel Old
Parallnel Old是Parallel Scavenge收集器的老年代版本,使用多线程和“标记-整理”算法。 - CMS
CMS(Concurrent Mark Sweep)收集器是一种以获取最短回收停顿时间为目标的收集器。该收集器是基于”标记-清除“算法实现的。
CMS收集器的收集过程分为以下4个步骤:
1、初始标记(Stop the World,标记GC Roots能直接关联到的对象)
2、并发标记(进行GC Roots Tracing的过程)
3、重新标记(Stop the World,休整并发标记期间因用户程序继续运行而导致标记产生变动的那一部分对象的标记记录)
4、并发清除(并发清除无用的对象)
缺点:
a、CMS收集器对CPU资源非常敏感,并发阶段占用的线程资源较多。
b、CMS收集器无法处理浮动垃圾。因为CMS并发清理阶段用户线程还在运行着,所以也会有相应的垃圾产生,这部分垃圾CMS无法在此次的收集中处理掉它们。
c、CMS收集器由于是基于“标记-清除”算法,故会产生较多的内存空间碎片。
新生代和老年代垃圾收集器
- G1
G1(Garbage-First)收集器所具备的特点:
1、并行和并发:使用多个CPU来缩短Stop-The-World的时间,部分垃圾收集器原本需要停顿Java线程执行的GC动作,G1收集器仍然可以通过并发的方式让Java程序继续执行。
2、分代收集
3、空间整合:标记-整理算法。
4、可预测的停顿。追求低停顿,并建立可预测的停顿时间模型,能让使用者明确指定在一个长度为M毫秒的时间片段内,消耗在垃圾收集上的时间不得超过N毫秒,达到了实时Java的垃圾收集器。
G1收集器分代策略:
G1收集器将整个Java堆划分为多个大小相等的独立区域(Region)。G1收集器之所以可以有计划地避免在整个Java堆中进行全区域的垃圾收据,是因为G1收集器跟踪各个Region里面的垃圾堆积的价值大小(回收获得的空间大小以及回收所需时间的经验值),在后台维护一个优先列表,每次根据允许的收集时间,优先回收价值最大的Region。即Grabage-First。
在G1收集器中,Region之间的对象引用以及其他收集器中的新生代与老年代之间的对象引用,虚拟机都是通过
Remembered Set来避免全堆扫描的。G1中每个Region都有一个与之对应的Remembered Set。在新建对象时,JVM会将相关的引用信息记录到被引用对象所属的Region的Remembered Set中。当进行回收时,在GC根节点的枚举范围中加入Remembered Set即可保证不对堆进行扫描也不会有遗漏。
G1收集器的手机阶段也分以下几个步骤:
1、初始标记(只是标记一下GC Roots能直接关联到的对象,并修改可以得Region中创建新对象,这阶段需要停顿线程,但耗时很短)
2、并发标记(从GC Roots开始对堆中对象进行可达性分析,找出存活对象)
3、最终标记(修正在并发标记期间因月洪湖程序继续运行而导致标记产生变动的那一部分标记记录)
4、筛选回收(首先对各个Regin的回收价值和成本进行排序,根据用户所期待的GC停顿时间指定回收计划,回收一部分Region)
最后,我们总结一下JVM中的垃圾收集器:
| 分类 | 所属分代 | 使用线程 | 使用算法 |
|---|---|---|---|
| Serial | 新生代 | 单线程 | 复制(新)、标记-整理(老) |
| ParNew | 新生代 | 多线程 | 复制(新)、标记-整理(老) |
| Parallel Scavenge | 新生代 | 多线程 | 吞吐量优先算法 |
| Serial Old | 老生代 | 单线程 | 复制(新)、标记-整理(老) |
| Parallel Old | 老生代 | 多线程 | 复制(新)、标记-整理(老) |
| CMS | 老生代 | 多线程 | 标记-清除算法(初始标记、并发标记、重新标记、并发清除) |
| G1 | 新生代&&老生代 | 多线程 | 标记-整理算法(初始标记、并发标记、最终标记、筛选回收) |
JVM总结(二):垃圾回收器的更多相关文章
- JVM总括二-垃圾回收:GC Roots、回收算法、回收器
JVM总括二-垃圾回收:GC Roots.回收算法.回收器 目录:JVM总括:目录 一.判断对象是否存活 为了判断对象是否存活引入GC Roots,如果一个对象与GC Roots没有直接或间接的引用关 ...
- JVM学习——G1垃圾回收器(学习过程)
JVM学习--G1垃圾回收器 把这个跨时代的垃圾回收器的笔记独立出来. 新生代:适用复制算法 老年代:适用标记清除.标记整理算法 二娃本来看G1的时候觉得比较枯燥,但是后来总结完之后告诉我说,一定要慢 ...
- JVM学习--(五)垃圾回收器
上一篇我们介绍了常见的垃圾回收算法,不同的算法各有各的优缺点,在JVM中并不是单纯的使用某一种算法进行垃圾回收,而是将不同的垃圾回收算法包装在不同的垃圾回收器当中,用户可以根据自身的需求,使用不同的垃 ...
- 说一下 jvm 有哪些垃圾回收器?
新生代收集器: SerialParNewParallel Scavenge 老年代收集器: Serial OldCMSParallel Old 堆内存垃圾收集器: G1 参考链接:JVM常见的垃圾回收 ...
- 【JVM】CMS垃圾回收器
一.简介 Concurrent Mark Sweep,是一种以获取最短回收停顿时间为目标的收集器,尤其重视服务的响应速度. CMS是老年代垃圾回收器,基于标记-清除算法实现.新生代默认使用ParNew ...
- JVM有哪些垃圾回收器
JVM 的垃圾回收器 目录 JVM 的垃圾回收器 经典垃圾收集器 Serial 收集器 ParNew 收集器 Parallel Scavenge 收集器 Serial Old 收集器 Parallel ...
- JVM几种垃圾回收器介绍
整理自:http://www.cnblogs.com/lspz/p/6397649.html 一.如何回收? 1.1 垃圾收集算法: (1)标记-清除(Mark-Sweep)算法 这是最基础的算法,就 ...
- jvm中的垃圾回收器
HotSpot JVM收集器 上面有7中收集器,分为两块,上面为新生代收集器,下面是老年代收集器.如果两个收集器之间存在连线,就说明它们可以搭配使用.Serial(串行GC)收集器 Serial收集器 ...
- JVM中的垃圾回收器及垃圾收集算法描述
首先需要了解下JVM(Java虚拟机)中的内存分配情况: 收集器的介绍: Serial收集器:是最原始的收集器,是单线程的,实现简单,但是在后台收集垃圾的时候,其他的工作线程都会停止,直到垃圾收集线程 ...
- JVM GC算法 垃圾回收器
JVM的垃圾回收算法有三种: 1.标记-清除(mark-sweep):啥都不说,直接上图 2.标记-整理(mark-compact) 3.复制(copy) 分代收集算法 ...
随机推荐
- HTML DOM 学习笔记
一.HTML DOM定义了所有HTML元素的对象和属性,以及访问他们的方法即:HTML DOM是关于如何获取,修改,添加,删除HTML元素的标准二.DOM节点1.分类整个文档是一个文档节点每个HTML ...
- PAT 1083 是否存在相等的差
https://pintia.cn/problem-sets/994805260223102976/problems/994805260780945408 给定 N 张卡片,正面分别写上 1.2.…… ...
- JS平滑无缝滚动实现———实现首页广告自动滚动效果(附实例)
本文我们实现纯JS方式的滚动广告效果. 先show一下成品: 首先是网页样式: 1. #demo { 2. background: #FFF; 3. overflow:hidden; 4. borde ...
- jquery遍歷
遍歷是什麼? jquery的遍歷指的是移動,就是從選中的元素根據元素之間的關係移動,直到找到目標元素.從DOM樹中,可以進行向上移動(祖先),向下移動(子孫)和水平移動(同胞). 祖先就是父,祖父,曾 ...
- BZOJ4229选择——LCT+并查集+离线(LCT动态维护边双连通分量)
题目描述 现在,我想知道自己是否还有选择. 给定n个点m条边的无向图以及顺序发生的q个事件. 每个事件都属于下面两种之一: 1.删除某一条图上仍存在的边 2.询问是否存在两条边不相交的路径可以从点u出 ...
- HDU-2087-KMP-水题
纯KMP #include <cstdio> #include <algorithm> #include <cstring> #include <ctype. ...
- 使用JQuery进行DOM操作
获得内容 - text().html() 以及 val() 三个简单实用的用于 DOM 操作的 jQuery 方法: text() - 设置或返回所选元素的文本内容 html() - 设置或返回所选元 ...
- MT【48】分式连加形式下求不等式解集的区间长度
] 评:此题有分析的味道在里面,用到了n次多项式的韦达定理,用到了零点存在定理以及代数基本定理:n次多项式在复数域上有n个根.
- 集成源码深度剖析:Fescar x Spring Cloud
Fescar 简介 常见的分布式事务方式有基于 2PC 的 XA (e.g. atomikos),从业务层入手的 TCC( e.g. byteTCC).事务消息 ( e.g. RocketMQ Hal ...
- 自学Aruba5.2-Aruba安全认证-有PEFNG 许可证环境的角色策略管理
点击返回:自学Aruba之路 自学Aruba5.2-Aruba安全认证- 有PEFNG 许可证环境的角色策略管理 导入许可后,可以对Role进行配置: 1. 系统自带的Role的可以修改的属性: 2. ...