《jvm学习笔记》GC算法
标记阶段
- 通过根节点,标记所有从根节点开始的可达对象
清除阶段
- 清楚所有未被标记的对象
标记-压缩
- 适用于存活对象较多的场合,如老年代。
- 从根节点开始标记可达对象
- 将存活对象压缩到内存的一端
- 清理边界外所有空间
复制算法
- 与标记-清除算法相比,复制算法是一种相对高效的回收方法
- 不适用于存活对象较多的场合 如老年代
- 将原有的内存空间分为两块,每次只使用其中一块,在垃圾回收时,将正在使用的内存中的存活对象复制到未使用的内存块中,之后,清除正在使用的内存块中的所有对象,交换两个内存的角色,完成垃圾回收
- 最大的问题:空间浪费
- 怎么解决?
- 大对象进入老年代,老年对象进入老年代
- 复制
分代思想
- 依据对象的存活周期进行分类,短命对象归为新生代,长命对象归为老年代。
- 根据不同代的特点,选取合适的收集算法
- 少量对象存活,适合复制算法
- 大量对象存活,适合标记清理或者标记压缩
可触及性
- 可触及的
- 从根节点可以触及到这个对象
- 可复活的
- 一旦所有引用被释放,就是可复活状态
- 因为在finalize()中可能复活该对象
- 不可触及的
- 在finalize()后,可能会进入不可触及状态
- 不可触及的对象不可能复活
- 可以回收
- 避免使用finalize()
- 优先级别低,GC何时被调用不确定
- try-catch-finally释放资源
- 根节点
- 栈中引用的对象
- 方法区中静态成员或常量
- JNI方法栈中引用对象
Stop - The - World
Java中一种全局暂停的现象
全局停顿,所有Java代码停止,native代码可以执行,但不能和JVM交互
多半由于GC引起
- Dump线程
- 死锁检查
- 堆Dump
GC时为什么会有全局停顿?
– 类比在聚会时打扫房间,聚会时很乱,又有新的垃圾产生,房间永远打扫不干净,只有让大家停止活动了,才能将房间打扫干净。
危害
– 长时间服务停止,没有响应
– 遇到HA系统,可能引起主备切换,严重危害生产环境。
GC参数
串行收集器
- 最古老,稳定
- 效率高
- 产生较长的停顿
- -XX:+UserSerialGC
- 新生代、老年代使用串行回收
- 新生代复制算法
- 老年代标记-压缩
并行收集器
- -XX:+UseParNewGC
- 新生代并行
- 老年代串行
- Serial收集器新生代的并行版本
- 复制算法
- 多线程,需要多核支持
- -XX:ParallelGCThreads 限制线程数量
Parallel收集器
- 类似ParNew
- 新生代复制算法
- 老年代 标记-压缩
- 更加关注吞吐量
- XX:+UseParallelGC
- 使用Parallel收集器+ 老年代串行
- XX:+UseParallelOldGC
- 使用Parallel收集器+ 并行老年代
CMS
并发标记清除(与用户线程一起执行)
标记-清楚算法
吞吐量降低
老年代收集器(新生代使用ParNew)
-XX:+UseConcMarkSweepGC
CMS运行过程比较复杂,着重实现了标记的过程,可分为
- 初始标记
- 根可以直接关联到的对象
- 速度快
- 并发标记(和用户线程一起)
- 主要标记过程,标 记全部对象
- 重新标记
- 由于并发标记时,用户线程依然运行,因此在正式清理前,再做修正
- 并发清除(和用户线程一起)
- 基于标记结果,直接清理对象
- 初始标记
尽可能降低停顿
会影响系统整体吞吐量和性能
清理不彻底
无法再空间快满时再清理
标记清除和标记压缩区别
- 标记清除会产生内存碎片,而标记压缩不会
以上是 《jvm学习笔记》GC算法 的全部内容, 来源链接: utcz.com/z/513117.html