Shenandoah 垃圾回收器是 Red Hat 在 2014 年宣布进行的一项垃圾收集器研究项目 Pauseless GC 的实现,旨在针对 JVM 上的内存收回实现低停顿的需求。该设计将与应用程序线程并发,通过交换 CPU 并发周期和空间以改善停顿时间,使得垃圾回收器执行线程能够在 Java 线程运行时进行堆压缩,并且标记和整理能够同时进行,因此避免了在大多数 JVM 垃圾收集器中所遇到的问题。

Shenandoah GC 主要目标是 99.9% 的暂停小于 10ms,暂停与堆大小无关等。

垃圾回收期的分类:
  • 按线程数分,可以分为串行垃圾回收器和并行垃圾回收器。

    • 串行回收指的是在同一时间段内只允许一件事情发生,简单来说,当多个CPU 可用时,也只能有一个CPU
      用于执行垃圾回收操作,井且在执行垃圾回收时,程序中的工作线程将会被暂停,当垃圾收集工作完成后
      才会恢复之前被暂停的工作线程,这就是串行回收。
    • 和串行回收相反,并行收集可以运用多个CPU 同时执行垃圾回收,因此提升了应用的吞吐量,不过并行回
      收仍然与串行回收一样,采用独占式,使用了“ Stop-the-world ”机制和复制算法。
  • 按照工作模式分,可以分为并发式回收器和独占式垃圾回收器。
    • 并发式垃圾回收器与应用程序线程交替工作,以尽可能减少应用程序的停顿时间。
    • 独占式垃圾回收器( Stop the world)一旦运行,就停止应用程序中的其他所有线程,直到垃圾回收过程完
      全结束。
  • 按碎片处理方式可分为压缩式垃圾回收器和非压缩式垃圾回收器。
    • 压缩式垃圾回收器会在回收完成后,对存活对象进行压缩整理,消除回收后的碎片。
    • 非压缩式的垃圾回收器不进行这步操作。
  • 按工作的内存区间,又可分为年轻代垃圾回收器老年代垃圾回收器
如何评估一款GC的性能
  • 吞吐量:程序的运行时间(程序的运行时间+内存回收的时间)。
  • 垃圾收集开销:吞吐量的补数,垃圾收集器所占时间与总时间的比例。
  • 暂停时间:执行垃圾收集时,程序的工作线程被暂停的时间。
  • 收集频率:相对于应用程序的执行,收集操作发生的频率。
  • 堆空间: Java 堆区所占的内存大小。
  • 快速: 一个对象从诞生到被回收所经历的时间。
Shenandoah GC工作原理:

其内存结构与 G1 非常相似,都是将内存划分为类似棋盘的region。整体流程与 G1 也是比较相似的,最大的区别在于实现了并发的 疏散(Evacuation) 环节,引入的 BrooksForwarding Pointer 技术使得 GC 在移动对象时,对象引用仍然可以访问。

Init Mark 启动并发标记阶段:

  1. 并发标记遍历堆阶段
  2. 并发标记完成阶段
  3. 并发整理回收无活动区域阶段
  4. 并发 Evacuation 整理内存区域阶段
  5. Init Update Refs 更新引用初始化 阶段
  6. 并发更新引用阶段
  7. Final Update Refs 完成引用更新阶段
  8. 并发回收无引用区域阶段
配置或调试 Shenandoah 的 JVM 参数:
  1. -XX:+AlwaysPreTouch:使用所有可用的内存分页,减少系统运行停顿,为避免运行时性能损失。
  2. -Xmx == -Xmsv:设置初始堆大小与最大值一致,可以减轻伸缩堆大小带来的压力,与 AlwaysPreTouch 参数配合使用,在启动时提交所有内存,避免在最终使用中出现系统停顿。
  3. -XX:+ UseTransparentHugePages:能够大大提高大堆的性能,同时建议在 Linux 上使用时将
    /sys/kernel/mm/transparent_hugepage/enabled 和/sys/kernel/mm/transparent_hugepage/defragv 设置为:madvise,同时与 AlwaysPreTouch 一起使用时,init 和 shutdownv 速度会更快,因为它将使用更大的页面进行预处理。
  4. -XX:+UseNUMA:虽然 Shenandoah 尚未明确支持 NUMA(Non-Uniform Memory Access),但最好启用此功
    能以在多插槽主机上启用 NUMA 交错。与 AlwaysPreTouch 相结合,它提供了比默认配置更好的性能。
  5. -XX:+DisableExplicitGC:忽略代码中的 System.gc() 调用。当用户在代码中调用 System.gc() 时会强制
    Shenandoah 执行 STW Full GC ,应禁用它以防止执行此操作,另外还可以使用 -
  6. XX:+ExplicitGCInvokesConcurrent,在 调用 System.gc() 时执行 CMS GC 而不是 Full GC,建议在有
    System.gc() 调用的情况下使用。
    不过目前 Shenandoah 垃圾回收器还被标记为实验项目,如果要使用Shenandoah GC需要编译时--with-jvmfeatures选项带有shenandoahgc,然后启动时使用参数
  7. -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC

Java12新特性 -- Shenandoah GC的更多相关文章

  1. Java12新特性 -- 默认生成类数据共享(CDS)归档文件

    默认生成类数据共享(CDS)归档文件 同一个物理机/虚拟机上启动多个JVM时,如果每个虚拟机都单独装载自己需要的所有类,启动成本和内 存占用是比较高的.所以Java团队引入了类数据共享机制 (Clas ...

  2. Java12新特性

    switch表达式(预览) 传统switch的缺点 匹配是自上而下的,如果忘记写break, 后面的case语句不论匹配与否都会执行; 所有的case语句共用一个块范围,在不同的case语句定义的变量 ...

  3. Java12新特性 -- switch表达式

    传统switch表达式的弊端: 匹配是自上而下的,如果忘记写break, 后面的case语句不论匹配与否都会执行: 所有的case语句共用一个块范围,在不同的case语句定义的变量名不能重复: 不能在 ...

  4. Java12新特性 -- 只保留一个 AArch64 实现

    现状 当前 Java 11 及之前版本JDK中存在两个64位ARM端口.这些文件的主要来源位于src/hotspot/cpu/arm 和 open/src/hotspot/cpu/aarch64 目录 ...

  5. Java12新特性 -- 可中断的 G1 Mixed GC

    G1是一个垃圾收集器,设计用于具有大量内存的多处理器机器.由于它提高了性能效率,G1垃圾收集器最终将取代CMS垃圾收集器. 该垃圾收集器设计的主要目标之一是满足用户设置的预期的 JVM 停顿时间. G ...

  6. Java12新特性 -- 增强G1,自动返回未用堆内存给操作系统

    Java 12 中增强了 G1 垃圾收集器关于混合收集集合的处理策略,这节主要介绍在 Java 12 中同时也对 G1垃圾回收器进行了改进,使其能够在空闲时自动将 Java 堆内存返还给操作系统,这也 ...

  7. Java11新特性 - Epsilon GC和ZGC

    Java11中新增了两个GC,Epsilon GC和ZGC. Epsilon垃圾收集器 A NoOp Garbage Collector 没有操作的垃圾收集器 JDK上对这个特性的描述是:开发一个处理 ...

  8. Java12新特性 -- 其他新增,移除,废弃项

    支持unicode 11 JDK 12版本包括对Unicode 11.0.0的支持.在发布支持Unicode 10.0.0的JDK 11之后,Unicode 11.0.0引 入了以下JDK 12中包含 ...

  9. Java12新特性 -- JVM 常量 API

    Java 12 中引入 JVM 常量 API,用来更容易地对关键类文件 (key class-file) 和运行时构件(artefact)的名义描述 (nominal description) 进行建 ...

随机推荐

  1. java验证邮件正则

    这里,本人从commons-validator包中源码,拷出部分内容,如下: private static final String EMAIL_REGEX = "^\\s*?(.+)@(. ...

  2. linux系统信息获取和上报

    通过调用shell命令获取系统信息,如cpu个数,cpu/内存磁盘使用情况,网络信息等. #include <stdio.h> #include <stdlib.h> #inc ...

  3. Chrome浏览器内部协议Chrome://收集

    Chromium 采用 Chrome:// 协议开头的形式, 规定了一系列的内部协议, 有的用来显示数据, 有的用来实现一些功能, 但对普通用户进行了屏蔽.在Chrome浏览器地址栏直接访问就好了! ...

  4. ThreadLocal源码原理以及防止内存泄露

    ThreadLocal的原理图: 在线程任务Runnable中,使用一个及其以上ThreadLocal对象保存多个线程的一个及其以上私有值,即一个ThreadLocal对象可以保存多个线程一个私有值. ...

  5. Alpha冲刺(7/10)——追光的人

    1.队友信息 队员学号 队员博客 221600219 小墨 https://www.cnblogs.com/hengyumo/ 221600240 真·大能猫 https://www.cnblogs. ...

  6. python开发笔记之zip()函数用法详解

    今天分享一篇关于python下的zip()函数用法. zip()是Python的一个内建函数,它接受一系列可迭代的对象作为参数,将对象中对应的元素按顺序组合成一个tuple,每个tuple中包含的是原 ...

  7. cookie插件|jq-cookie.js|使用详解

    1.设置一二级域名共用的cookie:设置domain为一级域名,可一.二级域名共用的cookie $.cookie('f_city','北京|101010100|,锦州|101070701|',{e ...

  8. ActiveMQ基础

    消息队列的作用 为什么使用ActiveMQ,不使用其他工具 下载安装包并启动 http://localhost:8161/admin/ (账号:admin:admin) Java实现步骤: // 1. ...

  9. AFL Fuzz安装及完成一次简单的模糊测试

    关于AFL fuzz AFL fuzz是一个模糊测试工具,它封装了一个GCC/CLang编译器,用于对被测代码重新编译的过程中进行插桩.插桩完毕后,AFL fuzz就可以给其编译过的代码输入不同的参数 ...

  10. volatile 关键词

    volatile 关键字指示一个字段可以由多个同时执行的线程修改. 出于性能原因,编译器,运行时系统甚至硬件都可能重新排列对存储器位置的读取和写入. 声明了 volatile 的字段不进行这些优化.这 ...