《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

回到顶部