栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

【JVM】-垃圾回收算法

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【JVM】-垃圾回收算法

一、判断垃圾的两种方法 (一)引用计数

如果某个地方引用了这个对象就+1,如果失效了就-1,当为 0 就会回收。

【JVM不可用】无法判定循环引用,造成内存泄漏

(二)可达性分析(hotspot)

在垃圾回收之前,沿着GC Root对象为起点的引用链,扫描对于堆中的对象,找不到则能被回收。

GC Root 根对象(不能被回收)

GC Root对象有哪些 ?

  1. Java虚拟机栈(栈帧的本地变量表)中引用的对象。
  2. 本地方法栈中JNI引用对象。
  3. 方法区中常量、类静态属性引用的对象。
五种引用

三色标记法

原版

不可达对象 + 两次标记后仍可回收 == 可回收对象

三色标记法与读写屏障

白色:尚未访问过。
黑色:本对象已访问过,而且本对象 【引用的其他对象】 也全部访问过了。
灰色:本对象已访问过,但是本对象 【引用的其他对象】 尚未全部访问完。 若全部访问后,会转换为黑色。

(1)多标-- 浮动垃圾

多标了E,导致E成为浮动垃圾(等下一轮GC,才被清除)

(2)漏标-- 读写屏障
var G = objE.fieldG;  // 白色E 引用      白色G
objE.fieldG = null;   // 灰色E 断开引用  白色G 
objD.fieldG = G;      // 黑色D 引用      白色G

尽管因为D重新引用了G,但因为D已经是黑色了,不会再重新做遍历处理。

结果:G会一直停留在白色集合中,最后被当作垃圾进行清除。 影响程序正确性,不可接受的。

二、垃圾回收算法 (一)标记清除

先标记需清除的对象,之后统一回收。

但是这种方法效率不高,会产生大量不连续的空间碎片,这些碎片很难被重复利用。

(二)标记整理

先标记存活对象,然后让所有存活对象向一端移动,之后清理端边界以外的内存,解决内存碎片问题。

缺点:要移动对象,需要频繁改动对象的引用地址,速度慢。

(三)标记复制 (新生代)

将可用内存按容量划分为大小相等的两块,每次只使用其中一块。
当使用的这块空间用完了,就将存活对象复制到另一块,再把已使用过的内存空间一次清理掉。

优点:不会有内存碎片
缺点: 需要占用双倍内存空间

三、分代垃圾回收

以上三种算法的具体实现

新生代:标记复制
老年代:标记清除 / 标记整理
垃圾回收流程:

(1)对象首先分配在伊甸园区域
(2)新生代空间不足时,触发 minorGC,伊甸园和 from 存活的对象使用 copy 复制到 to 中,存活的对象年龄加 1并且交换 from to 。

minor GC 会引发STW,暂停其它用户的线程。等垃圾回收结束,用户线程才恢复运行 。

当对象寿命超过阈值时,会晋升至老年代,最大寿命是15(4bit),寿命保存在对象头中 。

(3)当老年代空间不足,会先尝试触发 minor GC,如果之后空间仍不足,那么触发 full GC,STW的时间更长

回收阶段触发条件内容
Yong GC
Yong Coleection + 并发标记当老年代超过一定阈值
Mixed Collection对新生代混合区和老年代进行规模较大的收集
四、垃圾回收器

年轻代

回收器算法应用线程特点
Serial标记复制STW单线程 串行
ParNew(可与CMS搭配)标记复制
(Serial收集器的多线程版本)
STW并行多线程
Parallel Scavenge(可与Parallel Old搭配)标记复制STW并行多线程

老年代

回收器适用场景算法应用线程特点
Serial Oldmark-sweep-compact(标志-清扫-压缩)STW单线程 串行
Parallel Oldmark-sweep(标志-清扫)STW多线程并行
Parallel Old

并发垃圾回收器

回收器适用场景算法应用线程特点
CMS(Concurrent MarkSweep )并行,低暂停某阶段会stw并发
G1,低暂停某阶段会stw并发
(一)串行(标记+整理)

GC期间STW,不允许用户线程继续工作

(二)并行

(三)CMS:低延迟(标记+清除)

有划时代意义!

第一款真正意义上的并发收集器,它第一次实现了让垃圾收集线程与用户线程同时工作。

不幸的是,CMS作为老年代的收集器,新生代只能选择ParNew或者Serial收集器中的一个。

初始标记 -> 并发标记 -> 重新标记 -> 并发清理


初始标记:只是标记出GCRoots能直接关联到的对象(所有工作线程会STW短暂暂停)
并发标记:从Gc Roots的直接关联对象开始遍历整个对象图
重新标记:修正并发标记期间,【因用户程序继续运作而导致标记产生变动】
并发清除:清理【标记已经死亡的对象】,释放内存

  1. 基本不暂停用户线程(仍有STW,但时间很短)
  2. 当ConcurrentMarkSweep 收集失败时,临时启用Serial Old(该算法会完全阻止应用程序的运行)
JDK8默认
新生代:Parallel Scavenge (PS MarkCopy)
老年代:Parallel Old (PS MarkSweep)
五、参考博客

CMS垃圾回收器详解

相关 VM 参数
含义参数
堆初始大小-Xms
堆最大大小-Xmx 或 -XX:MaxHeapSize=size
新生代大小-Xmn 或 (-XX:NewSize=size + -XX:MaxNewSize=size )
幸存区比例(动态)-XX:InitialSurvivorRatio=ratio
和 -XX:+UseAdaptiveSizePolicy
幸存区比例
(默认8,新生代:伊甸园8, FROM 1,TO 1)
-XX:SurvivorRatio=ratio
晋升阈值-XX:MaxTenuringThreshold=threshold
晋升详情(打印)-XX:+PrintTenuringDistribution
GC详情(打印)-XX:+PrintGCDetails -verbose:gc
FullGC 前先MinorGC(默认打开)-XX:+ScavengeBeforeFullGC
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1027270.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号