当前位置: 首页 > 图灵资讯 > 技术篇> jvm-第四节垃圾回收器的细节实现

jvm-第四节垃圾回收器的细节实现

来源:图灵教育
时间:2023-06-28 14:44:25

垃圾回收器串 HostSpot 实现本知识点概况的细节

  1. 并发标记和三色标记
  2. 在不同的垃圾回收期(G1、CMS对比)下,GC并发泄漏标问题的处理方案
  3. 跨代引用
  4. 安全点和安全区域
  5. gc参数(理解)
  6. 其他垃圾回收期(理解)
并发标记和三色标记
  1. 三色标记诞生的历史:三色标记前有一个标记清除算法。根据可达性,可达性设置为1,不可达性设置为0。完成后,可以统一清理,但不能异步。因此,stw需要很长时间。对于需要实时性的系统,如果不可接受,则有可异步的三色标记
  2. 三色标记的概念:三色分别是黑色 灰 白色,支持并发
  1. 黑色:跟随对象,所有引用都被扫描
  2. 灰色:扫描本身,但引用的对象尚未扫描
  3. 白:未扫描
与不同垃圾回收期下的处理方案(G1、Cms对比)相比,GC并发漏标问题
  1. 三色标记遗漏问题:原因是在并发扫描过程中,引用发生了变化,以下三张图片为例
  1. 下图描述了扫描时引用的变化
  1. 如何解决这个漏标问题,以下是cms和g1的解决方案
  1. incremental解决漏标的cms update:当一个白色对象被一个黑色对象引用时,将黑色标记为灰色并重新扫描;
  2. satbbg1解决漏标:stab是快照。当一个对象被修改时,它将被标记,然后颜色将改为灰色,并在下次回收时进行处理。标记为黑色
跨代引用
  1. 跨代引用的问题:堆分为新一代、老一代,如果老一代的对象引用了新一代的对象,新一代的回收就会扫描整个老一代,费用太高,
  2. 解决方案1-记忆集:rset,相当于一个位图记录,新生代和老年人之间的引用关系可以避免扫描整个老年人
  3. 解决方法2-cardTable:是记录堆内存区域是否修改的数据结构,按页面划分表格,记录修改后的页面,垃圾回收时只扫描dirty页面,避免全面扫描
安全点和安全区域
  1. 安全点功能:所有线程进入安全点,用户线程暂停,GC线程开始工作
  2. 什么是安全点:例如,方法调用、循环跳转和异常跳转。一般来说,这些指令会产生安全点。在执行过程中,用户线程将继续轮换安全点。如果发现为true,则主动将其挂在最近的安全点上
  3. 安全区域的作用:所有线程进入安全点,用户线程暂停,GC线程开始工作;代码引用关系不会改变;其次,如果线程一直是sleep,block,程序不能进入安全点,
  4. 什么是安全区?举个例子 sychronized

private static Selector selector;private static void processRequests() {    // 进入安全区    synchronized(selector) {        // 在安全区域内进行 I/O 操作        selector.select();        // 处理 I/O 事件        Set<SelectionKey> selectedKeys = selector.selectedKeys();        Iterator<SelectionKey> keyIterator = selectedKeys.iterator();        while(keyIterator.hasNext()) {            SelectionKey key = keyIterator.next();            if(key.isAcceptable()) {                // 处理连接请求            } else if (key.isReadable()) {                // 处理读事件            } else if (key.isWritable()) {                // 处理写事件            }            keyIterator.remove();        }    }    // 离开安全区,其它计算    // ...}

gc参数(理解)
  1. 上面是一个gc日志
  2. GC常用参数

GC 常用参数-Xmn -Xms -Xmx –Xss 年轻代 最小堆 最大堆 栈空间-XX:+UseTLAB 使用 TLAB,默认打开-XX:+PrintTLAB 打印 TLAB 的使用情况-XX:TLABSize 设置 TLAB 大小-XX:+DisableExplicitGC 用于禁用对调用处理的选项 System.gc() -XX:+PrintGC 查看 GC 基本信息-XX:+PrintGCDetails 查看 GC 详细信息-XX:+PrintHeapAtGC 每次一次 GC 后,打印堆信息-XX:+PrintGCTimeStamps 启用在每个 GC 打印时间戳的功能-XX:+PrintGCApplicationConcurrentTime 打印应用程序时间(低) -XX:+PrintGCApplicationStoppedTime 打印暂停时间(低)-XX:+PrintReferenceGC 记录回收了多少种不同类型的引用(重要性低)-verbose:class 详细的类加载过程-XX:+PrintVMOptions 当程序运行时,打印虚拟机接收的命令行显示参数-XX:+PrintFlagsFinal -XX:+PrintFlagsInitial 打印所有的 JVM 参数,查看一切 JVM 参数启动的初始值(必须使用)-XX:MaxTenuringThreshold 升代年龄,最大值 15, 并行(吞吐量)收集器的默认值为 15,而 CMS 收集器的默认值为 6。 Parallel 常用参数-XX:SurvivorRatio 设置伊甸园空间大小与幸存者空间大小之间的比例。在默认情况下,该选项设置为 8-XX:PreTenureSizeThreshold 大对象有多大,大于这个值的参数直接在老年人分配-XX:MaxTenuringThreshold 升级年龄,最大值 15, 并行(吞吐量)收集器的默认值为 15,而 CMS 收集器的默认值为 6。-XX:+ParallelGCThreads 并行收集器的线程数也适用于 CMS,一般设为和 CPU 核数相同-XX:+UseAdaptiveSizePolicy CMS自动选择各区大小比例CMS 常用参数-XX:+UseConcMarkSweepGC 启用 CMS 垃圾回收器-XX:+ParallelGCThreads 并行收集器的线程数也适用于 CMS,一般设为和 CPU 核数相同

其他垃圾回收器(理解)
  1. 传统的垃圾回收期:内存占用、吞吐量、延迟只能满足两个要求,现在延迟指标越来越重要,有低延迟垃圾回收器

Eplison(了解)这个垃圾回收器不能进行垃圾回收,是一个“不工作”的垃圾回收器,由 RedHat 退出时,还负责堆的管理和布局、对象的分配、与解释器的合作、与编译器的合作、与监控子系统的合作,主要用于需要剥离垃圾收集器影响的性能测试和压力测试。ZGC(了解)有类似的相似之处 G1 的 Region,但是没有分代。标志性设计是染色指针 ColoredPointers(可以理解这个概念),染色指针有 4TB 内存限制,但效率极高,是一种在指针上存储少量额外信息的技术。它几乎可以实现整个收集过程的并发性和短期性 STW 也只与 GC Roots 大小与堆空间内存的大小无关,因此考试科目1实现了任何堆空间 STW 目标时间小于10毫秒。Shenandoah(了解)第一款不是 Oracle 该公司开发的垃圾回收器,类似于 G1 的 Region,但没有分代。还使用了染色指针 ColoredPointers。效率没有 ZGC 目标高,几十毫秒左右。

问题
  1. 垃圾回收器 从cms到g1发展的变化,如漏标处理、跨代引用处理等;
  2. 安全点与安全区域的区别

上一篇:

JVM类加载机制

下一篇:

Java NIO