阅读 134

垃圾回收器

垃圾回收器

1. 垃圾回收器组合关系:

 垃圾回收器组合关系

 

  • Serial GC:串行垃圾回收器,作用于新生代,收集器采用复制算法,搭配 Serial Old GC 共同使用,在 HotSpot JVM 中,使用命令:

    •  -XX:+UseSerialGC:使用 Serial GC 和 Serial Old GC 组合垃圾回收器

  • Serial Old GC:串行垃圾回收器,作用于老年代,收集器采用标记-压缩算法,搭配 Serial GC 共同使用,也可以作为 CMS GC 的兜底垃圾回收器。

  • ParNew GC:并行垃圾回收器,作用于新生代,收集器采用复制算法,老年代可以搭配 Serial Old GC 或 CMSGC 共同使用。

    • -XX:ParallelGCThreads:限制线程数量,默认开启和 CPU 数据相同的线程数

    • -XX:+UseParNewGC:新生代使用 ParNew GC,当前 JVM 已经不推荐使用这个命令

  •  Parallel Scavenge GC:作用于新生代收集器,收集器采用标记-压缩算法,相比于 ParNew GC,Parallel Scavenge GC 目标则是达到一个可控制的吞吐量,它也被称为吞吐量优先的垃圾收集器,自适应调节策略也是 Parallel Scavenge GC 与 ParNew GC 的一个重要区别,Parallel Scavenge GC 可以 Parallel Old GC 用于老年代的收集。

    • -XX:UseParallelGC:使用 Parallel Scavenge GC + Parallel Old GC 组合策略,也是 JDK6-JDK8 的默认垃圾回收器

    • -XX:UseParallelOldGC:与 -XX:UseParallelGC 互相关联,启动一个另一个也会被开启

    • -XX:ParallelGCThreads:设置年轻代  Parallel Scavenge GC 线程数

    • -XX:MaxGCPauseMillis:设置垃圾回收器最大停顿时间(即 STW 的时间),单位是毫秒

    • -XX:GCTimeRatio:垃圾收集时间占总时间的比例(= 1 / (N + 1))。用于衡量吞吐量大小。默认 99,也就是垃圾回收时间不超过 1%。,与 -XX:MaxGCPauseMillis 参数有一定矛盾性

    • -XX:+UseAdaptiveSizePolicy:设置 Parallel Scavenge GC 具有自适应调节策略。在这种模式下,年轻代的大小、Eden 和 Survivor 的比例、晋升老年代的对象年龄等参数会被自动调整,已达到在堆大小、吞吐量和停顿时间之间的平衡点。

  • CMS:并发收集处理器,作用于老年代,收集器采用标记整理算法,在新生代,可以搭配 Serial 或 ParNew 使用,在老年代,如果需要内存碎片整理或使用 CMS 失败,可以使用 Serial Old 兜底。

    • -XX:+UseConcMarkSweepGC:指定 CMS 作为老年代垃圾收集器,开启将会自动将 -XX:UseParNewGC 打开

    • -XX:CMSInitiatingOccupanyFraction:设置内存使用率阈值,一旦超过该阈值,便开始回收。

    • -XX:+UseCMSCompactAtFullCollection:用于指定在执行完 Full GC 后对内存进行压缩整理,以避免内存碎片的产生

    • -XX:CMSFullGCBeforeCompaction:设置在执行多少次 Full GC 后对内存空间进行压缩整理

    • -XX:ParallelCMSThreads:设置CMS 线程数,默认 (ParallelGCThreads + 3) / 4

  • G1:兼具并发和并行特性的垃圾收集器,可以同时作用于老年代和新生代。

    • -XX:+UseG1GC:手动指定使用 G1 收集器

    • -XX:G1HeapReagionSize:设置每个Region大小,值是 2 的幂,范围 1MB-32MB之间,目标是根据最小 Java 堆大小分出约2048 个区域,默认堆内存的 1/2000

    • -XX:MaxGCPauseMillis:设置期望达到的最大GC 停顿时间(JVM 会尽力实现,但不保证达到)默认 200ms

    • -XX:ParalledGCThread:设置 STW 工作线程数,最大为 8

    • -XX:ConcGCThreads:设置并发标记线程数,一般设置为 ParalledGCThread 的 1/4 左右

    • -XX:InitiatingHeapOccupancyPercent:设置触发GC周期的Java 堆占用率阈值,超过此值,触发 GC。默认 45

    • -XX:G1MixedGCCountTarget:G1 混合垃圾回收测目标次数

    • -XX:G1HeapWastePercent:G1 Region 中垃圾占用率阈值,低于这个阈值的 Region 不会被回收,默认 10%

2. CMS 处理流程:

  • 初始标记:这个阶段,程序中所有的工作线程都将会 STW,这个阶段仅仅只标记出 GC Roots 能够直接关联到的对象。标记完成恢复工作线程,所以这里速度非常快。

  • 并发标记:从 GC Roots 的直接关联对象开始遍历整个对象图的过程,这个过程耗时较长,但不需要 STW,垃圾收集器可以和工作线程并发运行。

  • 重新标记:为了修复并发标记期间,因用户程序运行而导致标记产生变动的那一部分对象的标记记录,这个阶段的停顿时间通常比初始标记时间长一些,但远比并发标记时间短。

  • 并发清除:清理删除标记阶段判断的已经死亡的对象,释放内存空间。这个阶段垃圾收集器也可以和工作线程并发运行。JDK5默认68,JDK6及以上默认92。如果内存增长缓慢,可以设大点,反之则可以设小一点。

 3. G1 处理流程:Remembered Set

 3.1 G1 使用 Remembered Set 原因:一个 Region 不可能是孤立的,一个 Region 中的对象可能被其他任意 Region 中对象引用,此时回收新生代也不得不同时扫描老年代,这样会降低 Minor GC 效率

 3.2 使用 Remembered Set 解决方案:

  • 无论 G1 还是其他分带收集器,JVM 都是使用 Remembered Set 来避免全局扫描

  • 每个 Region 都有一个对应的 Remembered Set,每次 Reference 类型数据写操作时,都会产生一个 Write Barrier 暂时中断操作,然后检查将要写入的引用指向的对象是否和该 Reference 类型数据在不同的 Region(其他收集器:检查老年代对象是否引用了新生代对象),如果不同,通过 CardTable 把相关引用信息记录到引用指向对象所在 Region 对应的 Remembered Set 中,当进行垃圾收集时,在 GC 根节点的枚举范围加入 Remembered Set;就可以保证不进行全局扫描,也不会有遗漏。

4. G1 处理流程:并发标记过程:

  1. 初始标记阶段:标记从根节点直接可达的对象。这个阶段是 STW 的,并且会触发一次 年轻代 GC

  2. 根区域扫描:G1 扫描 Survivor 区直接可达的老年代区域对象,并标记被引用的对象,这一过程必须在 young GC 之前完成

  3. 并发标记:在整个堆中进行并发标记(和应用程序并发执行),此过程可能被 young GC 中断。在并发标记阶段,若发现区域对象中的所有对象都是垃圾,那这个区域会被立即回收。同时,并发标记过程中,会计算每个区域的对象存活的比例

  4. 再次标记:修正并发标记的标记结果。需要 STW,G1 中采用了比 CMS 更快的初始快照算法 (SATB)

  5. 独占清理:需要 STW,计算各个区域的存活对象和 GC 回收比例并进行排序,识别可以混合回收的区域,为下一阶段做铺垫,这一阶段并不会实际上去做垃圾收集

  6. 并发清理:识别并清理完全空闲的区域

5. G1 处理流程:混合回收:

  • 并发标记后,老年代中百分百垃圾的内存分段被直接回收,部分为垃圾的内存分段被计算出来,默认情况下,这些老年代内存分段会分 8 次(可以通过 -XX:G1MixedGCCountTarget 设置)被回收。

  • 混合回收集包括 1/8 的老年代内存分段,Eden 区内存分段,Survivor 区内存分段。混合回收的算法和年轻代回收算法完全一样,只是回收集多了老年代内存分段。

  • 由于老年代中的内存分段默认分 8 次回收,G1 会优先回收垃圾多的内存分段。垃圾占内存分段比例越高,越会被优先回收。并且有一个阈值会决定内存分段是否被回收,-XX: G1MixedGCLiveThresholdPercent,默认为 65%,意思是占内存分段要达到 65%才会被回收。如果垃圾占比太低,意味着存回的对象占比高,在复制的时候会花费更多的时间

  • 混合回收并不一定要进行 8 次。有一个阈值 -XX:G1HeapWastePercent,默认为 10%,意思是允许整个堆内存中有 10% 的空间被浪费,意味着如果发现可以回收的垃圾占堆内存的比例低于 10%,则不再进行垃圾回收。

6. G1 优化建议:

  • 年轻代避免使用 -Xmn 或 -XX:NewRatio 等相关选项显示设置年轻代大小,如果固定年轻代大小会覆盖暂停时间目标

  • 暂时时间目标不要太过严苛,G1 的吞吐量目标是 90% 的应用程序时间和 10% 的垃圾回收时间,如果暂停时间太过严苛会直接影响到吞吐量,且每次暂停时间太短会导致垃圾回收区域变少,多次积累之后出现 Full GC 的频率也会变高

 

来源https://www.cnblogs.com/programmlover/p/15085164.html

文章分类
后端
文章标签
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐