知识库
并发编程
  • 分类
  • 标签
  • 归档
友情连接

luoliang

吾生也有涯,知也无涯
并发编程
  • 分类
  • 标签
  • 归档
友情连接
  • 类加载子系统
  • JVM的整体结构
  • JVM的垃圾回收
    • 前言
    • 垃圾回收算法
    • 垃圾回收器
      • Serial收集器
      • ParNew收集器
      • Parallel Scavenge收集器
      • Serial Old收集器
      • Parallel Old收集器
      • CMS收集器
      • G1收集器
      • 垃圾回收过程
      • G1收集器的优点
      • 垃圾收集分类
      • 核心参数
      • ZGC收集器
      • 设计目标
    • 参考
  • arthas排查问题
  • jvm
weiluoliang
2024-04-10
目录

JVM的垃圾回收

# 前言

垃圾的定义: 不再被引用的对象就是垃圾。 那如何判断一个对象是否被引用呢?

  • 引用计数法 用一个标记记录引用次数,当引用次数为0时,就是垃圾
  • 可达性分析法 从GC Roots开始,遍历所有对象,如果对象不可达,就是垃圾。

# 垃圾回收算法

  • 标记-清除算法 先标记好回收的对象,然后统一回收
  • 标记-压缩算法 标记好回收的对象,然后将存活的对象压缩到一端,然后回收另一端的空间
  • 复制算法 将内存分为两块,每次只使用一块,当这一块满了,就将存活的对象复制到另一块,然后回收这一块
  • 分代算法 根据对象的存活周期将内存分为不同的区域,然后根据不同的区域使用不同的算法

# 垃圾回收器

垃圾回收器是实现垃圾回收算法的具体实现,根据不同的算法和实现,可以分为以下几种 先看一张图,了解一下各个垃圾回收器的关系

img

# Serial收集器

在新生代使用复制算法,在老年代使用标记-清除算法

  • 使用单线程进行回收

优点:简单高效,没有线程切换的开销 缺点:无法充分利用多核CPU

# ParNew收集器

使用复制算法,多线程进行回收,可以和CMS收集器配合使用

# Parallel Scavenge收集器

使用复制算法,多线程进行回收

# Serial Old收集器

用于老年代的收集器,使用标记-清除算法

# Parallel Old收集器

# CMS收集器

CMS(Concurrent Mark Sweep)收集器,是一种以获取最短回收停顿时间为目标的收集器. 使用标记-清除算法,分为以下几个阶段

  • 初始标记 标记GC Roots能直接关联到的对象(STW)
  • 并发标记 标记所有对象
  • 重新标记 修正并发标记期间因用户程序继续运行导致标记产生变动的对象(STW)
  • 并发清除 清除对象
  • 并发清理 清理对象

img

# G1收集器

G1 (Garbage-First)收集器,最大的特点是可以设置期望停顿时间,然后在这个时间内尽可能多的进行垃圾回收。 不再区分新生代和老年代,而是将内存分为多个区域,每个区域都可以是新生代或者老年代。

region的类型有以下几种:

  • Eden 堆内存默认占比 5%
  • Survivor 新生代存货区
  • Old 老年代区域
  • Humongous 超过region50%大小的对象被确认为大对象,会被放到Humongous区域

# 垃圾回收过程

  • 初始标记 标记GC Roots能直接关联到的对象(STW)
  • 并发标记 标记所有对象
  • 最终标记 修正并发标记期间因用户程序继续运行导致标记产生变动的对象(STW)
  • 筛选回收 选择回收对象

img

# G1收集器的优点

  • 并行与并发 G1在并行处理的同时,也能与应用程序并发执行,充分利用多核CPU
  • 分代收集 G1不再区分新生代和老年代,而是将内存分为多个区域,每个区域都可以是新生代或者老年代
  • 空间整合 G1收集器会进行空间整合,减少内存碎片
  • 可预测的停顿 G1可以设置期望停顿时间,然后在这个时间内尽可能多的进行垃圾回收

# 垃圾收集分类

  • Young GC 并不是Eden区满了马上出发Young GC,而是会去计算Eden去回收大概要多久时间,如果远远小于期望停顿时间,而是增加Eden区的使用,等到下一次Eden区满了,再计算一次,如果大于期望停顿时间,就会触发Young GC。
  • Mixed GC 老年代的堆占有率达到设置的值(-XX:InitiatingHeapOccupancyPercent)则触发Mixed GC,回收所有的Young和部分old(根据预期停顿时间)和大对象,一般会先做mixed GC,使用复制算法进行, 把region中的存活对象复制到其他region中,然后清理掉这个region,这样可以减少碎片,如果没有足够的内存存放这些对象则会触发Full GC。
  • Full GC 使用单线程进行,系统会停止所有的应用线程,进行垃圾回收,这个过程会比较长,会导致系统停顿。使用标记-清除算法,然后进行空间整理。

# 核心参数

  • -XX:+UseG1GC:使用G1收集器
  • -XX:MaxGCPauseMillis 设置期望停顿时间
  • -XX:G1HeapRegionSize 设置region的大小
  • -XX:InitiatingHeapOccupancyPercent 设置老年代的堆占有率达到多少时触发Mixed GC
  • -XX:G1MixedGCLiveThresholdPercent 设置Mixed GC后存活对象占比多少时触发Full GC

# ZGC收集器

优点:

  • GC时间能控制在10ms范围内
  • GC时长只跟GC Roots有关,跟存活对象没有关系

关键技术:

  • 着色指针
  • 读屏障

# 设计目标

  • 停顿时间不超过10ms
  • 停顿时间不会随着堆内存的增加而增加
  • 支持TB级别的堆内存(8MB~4TB)

# 参考

  • 美团技术-新一代垃圾回收器ZGC的探索与实践 (opens new window)
  • 美团技术-Java Hotspot G1 GC的一些关键技术 (opens new window)
  • Java中9种常见的CMS GC问题分析与解决 (opens new window)
  • 从实际案例聊聊Java应用的GC优化 (opens new window)
上次更新: 2024/04/22, 10:37:52
JVM的整体结构
arthas排查问题

← JVM的整体结构 arthas排查问题→

最近更新
01
Linux常用命令
09-04
02
SpringBoot启动脚本
08-31
03
安装监控grafana
08-30
更多文章>
Theme by Vdoing | Copyright © 2022-2024 Evan Xu | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式