来自 周志明的《深入理解Java虚拟机(第3版)》的读书笔记
Java对象是否存活 Java垃圾收集算法 经典垃圾收集器 Java HotSpot的算法细节实现 Java HotSpot虚拟机的垃圾收集器1.Java 对象是否存活
1.1 引用计数算法(Reference Counting)
主流的Java虚拟机没有采用此种算法
缺点
占用额外的内存空间
一些例外情况的处理,如:对象之间的循环引用问题
1.2 可达性分析算法(Reachability Analysis)
基本思路
如果某个对象到 GC Roots间没有任何引用链相连,则无使用,要被GC
可作为GC Roots的对象
1.3 再谈引用
种类
强引用
不回收
软引用
可二次回收
还有用但非必须回收的对象
弱引用
会被回收
虚引用
被回收
设置的目的:为了对象在GC时收到一个系统通知
1.4 生存还是死亡(对象的自我拯救)
对象不可达后再标记两次,才会被回收
是否有必要执行finalize()方法
只会自救一次
一个对象finalize()方法最多一次调用
1.5 回收方法区
回收成果低
回收内容
废弃的常量
不再使用的类型
2. Java 垃圾收集算法
2.1 概述
划分
引用计数式垃圾收集(直接垃圾收集)
追踪式垃圾收集(间接垃圾收集)
分代收集理论
两个分代假说
弱分代假说(朝生夕死)
强分代假说(熬下来)
跨代引用假说
定义/分类
部分收集(Partial GC)
新生代收集
老年代收集
混合收集
整堆收集(Full GC)
2.2 标记—清理算法(Mark-Sweep)
缺点
执行效率不稳定
内存空间的碎片化问题
2.3 标记—复制算法
半区复制
Appel式回收
80% Eden
10% Survivor
10% Survivor
3. Java HotSpot的算法细节实现
3.1 根节点枚举
必须暂停用户线程(Stop The World)
准确式垃圾收集
OopMap
3.2 安全点(Spfepoint)
概念
只在特定位置为指令生成OopMap,这些位置成为“安全点”
实现
抢先式中断
用的很少
主动式中断
设置标志位,不断轮询
3.3 安全区域(Safe Region)
产生背景
程序“不执行”时,线程无法响应虚拟机中断
概念
确保在某一段代码片段中,引用关系不会发生变化
3.4 记忆集与卡表
避免整个老年代加入GC Roots扫描
记录精度
字长精度
对象精度
卡精度
卡表
最常用,是记忆集的默认实现
卡页
写屏障(Writer Barrier)
卡表元素何时变脏
有其他分代区域引用了本区域对象时
用来维护卡表状态
“引用类型字段赋值”的AOP切面
高并发下的"伪共享"问题
3.5 并发的可达性分析
用户线程和收集器并发工作
黑、灰、白三色演示
解决方案
增量更新
原始快照
4. 经典垃圾收集器
4.1 Serial收集器
单线程
会有Stop The World的暂停
运行在客户端模式下的虚拟机的默认收集器
4.2 ParNew收集器
Serial收集器的多线程并发版本
工作在新生代,与老年代的CMS配合使用
4.3 Parallel Scavenge收集器
吞吐量优化收集器
4.4 Serial Old收集器
4.5 Parallel Old收集器
4.6 CMS收集器(Concurrent Mark Sweep)
过程
初始标记
并发标记
重新标记
并发清除
缺点
对处理器资源很敏感
无法处理“浮动垃圾”
基于"标记-清理"算法实现会有空间碎片产生
4.7 Garbage First收集器
基于Region的堆内存布局
收集4步骤
初始标记
并发标记
最终标记
筛选回收
网友评论