FantasticMao 技术笔记
BlogGitHub
  • README
  • C & Unix
    • C
      • 《C 程序设计语言》笔记
      • C 语言中的陷阱
      • CMake 示例
      • GNU make
      • LLVM Clang
      • Nginx 常用模块
      • Vim 常用命令
    • Unix-like
      • 《深入理解计算机系统》笔记
      • 《UNIX 环境高级编程》笔记 - UNIX 基础知识
      • 《UNIX 环境高级编程》笔记 - 文件 IO
      • 《UNIX 环境高级编程》笔记 - 标准 IO 库
      • 《鳥哥的 Linux 私房菜》笔记 - 目录配置
      • 《鳥哥的 Linux 私房菜》笔记 - 认识与学习 bash
      • 《鳥哥的 Linux 私房菜》笔记 - 任务管理
      • OpenWrt 中的陷阱
      • iptables 工作机制
  • Go
    • 《A Tour of Go》笔记
    • Go vs C vsJava
    • Go 常用命令
    • Go 语言中的陷阱
  • Java
    • JDK
      • 《Java 并发编程实战》笔记 - 线程池的使用
      • 设计模式概览
      • 集合概览
      • HashMap 内部算法
      • ThreadLocal 工作机制
      • Java Agent
    • JVM
      • 《深入理解 Java 虚拟机》笔记 - Java 内存模型与线程
      • JVM 运行时数据区
      • 类加载机制
      • 垃圾回收算法
      • 引用类型
      • 垃圾收集算法
      • 垃圾收集器
    • Spring
      • Spring IoC 容器扩展点
      • Spring Transaction 声明式事务管理
      • Spring Web MVC DispatcherServlet 工作机制
      • Spring Security Servlet 实现原理
    • 其它
      • 《Netty - One Framework to rule them all》演讲笔记
      • Hystrix 设计与实现
  • JavaScript
    • 《写给大家看的设计书》笔记 - 设计原则
    • 《JavaScript 权威指南》笔记 - jQuery 类库
  • 数据库
    • ElasticSearch
      • ElasticSearch 概览
    • HBase
      • HBase 数据模型
    • Prometheus
      • Prometheus 概览
      • Prometheus 数据模型和指标类型
      • Prometheus 查询语法
      • Prometheus 存储原理
      • Prometheus vs InfluxDB
    • Redis
      • 《Redis 设计与实现》笔记 - 简单动态字符串
      • 《Redis 设计与实现》笔记 - 链表
      • 《Redis 设计与实现》笔记 - 字典
      • 《Redis 设计与实现》笔记 - 跳跃表
      • 《Redis 设计与实现》笔记 - 整数集合
      • 《Redis 设计与实现》笔记 - 压缩列表
      • 《Redis 设计与实现》笔记 - 对象
      • Redis 内存回收策略
      • Redis 实现分布式锁
      • Redis 持久化机制
      • Redis 数据分片方案
      • 使用缓存的常见问题
    • MySQL
      • 《高性能 MySQL》笔记 - Schema 与数据类型优化
      • 《高性能 MySQL》笔记 - 创建高性能的索引
      • 《MySQL Reference Manual》笔记 - InnoDB 和 ACID 模型
      • 《MySQL Reference Manual》笔记 - InnoDB 多版本
      • 《MySQL Reference Manual》笔记 - InnoDB 锁
      • 《MySQL Reference Manual》笔记 - InnoDB 事务模型
      • B-Tree 简述
      • 理解查询执行计划
  • 中间件
    • gRPC
      • gRPC 负载均衡
    • ZooKeeper
      • ZooKeeper 数据模型
    • 消息队列
      • 消息积压解决策略
      • RocketMQ 架构设计
      • RocketMQ 功能特性
      • RocketMQ 消息存储
  • 分布式系统
    • 《凤凰架构》笔记
    • 系统设计思路
    • 系统优化思路
    • 分布式事务协议:二阶段提交和三阶段提交
    • 分布式系统的技术栈
    • 分布式系统的弹性设计
    • 单点登录解决方案
    • 容错,高可用和灾备
  • 数据结构和算法
    • 一致性哈希
    • 布隆过滤器
    • 散列表
  • 网络协议
    • 诊断工具
    • TCP 协议
      • TCP 报文结构
      • TCP 连接管理
由 GitBook 提供支持
在本页
  • 经典收集器之间的关系
  • 新生代
  • Serial 收集器
  • ParNew 收集器
  • Parallel Scavenge 收集器
  • 老年代
  • Parallel Old 收集器
  • CMS 收集器
  • Mixed GC
  • Garbage First 收集器
  1. Java
  2. JVM

垃圾收集器

经典收集器之间的关系

+-----------------------+-----------------------+
| Young Generation      |                       |
|        +------+       |       +---+           |
|        |Serial|-------+-+-----|CMS|           |
|        +------+       |  \   /+---+           |
|                       |    x                  |
|        +------+       |  /   \+----------+    |
|        |ParNew|-------+-+-----|Serial Old|    |
|        +------+       |      /+----------+    |
|                       |    /                  |
|      +--------+       |  /    +------------+  |
|      |Parallel|-------+-+-----|Parallel Old|  |
|      |Scavenge|       |       +------------+  |
|      +--------+    +------+                   |
|                    |  G1  |                   |
|                    +------+                   |
|                       |    Tenured Generation |
+-----------------------+-----------------------+

新生代

Serial 收集器

Serial 收集器是一个单线程工作的收集器,它在进行垃圾回收时,必须暂停其它所有工作线程,直到垃圾回收结束。

Serial 收集器适用于运行在客户端模式或者是单核处理器下的虚拟机。

ParNew 收集器

ParNew 收集器实质上是 Serial 收集器的多线程并行版本。

ParNew 收集器默认开启的收集器线程数与处理器核心数量相同,在处理器核心非常多的环境中,可以使用参数 -XX:ParallelGCThreads 来限制垃圾收集的线程数。

Parallel Scavenge 收集器

Parallel Scavenge 收集器关注的目标是垃圾回收的吞吐量,被称为「吞吐量优先收集器」。

Parallel Scavenge 收集器提供了两个参数用于精确控制吞吐量大小的:

  • -XX:MaxGCPauseMillis 控制最大垃圾回收的停顿时间;

  • -XX:GCTimeRatio 直接设置吞吐量大小。

Parallel Scavenge 收集器还提供了一个参数 -XX:UseAdaptiveSizePolicy,用于指示虚拟机根据当前系统运行的情况收集性能监控信息,动态调整这些参数以提供最合适的停顿时间或者最大的吞吐量。这种调节方式被成为垃圾收集器的自适应调节策略。

老年代

Parallel Old 收集器

Parallel Old 是 Parallel Scavenge 收集器的老年代版本。

CMS 收集器

CMS(Concurrent Mark Sweep)收集器是一种以获取最短停顿时间为目标的收集器。

CMS 收集器基于标记 - 清除算法实现,整个过程分为四个步骤:

  1. 初始标记(CMS initial mark),仅标记 GC Roots 能直接关联到的对象,速度很快;

  2. 并发标记(CMS concurrent mark),从 GC Roots 直接关联的对象开始遍历整个对象图,过程比较长但是不需要停顿工作线程,可以与垃圾收集线程一起并发运行;

  3. 重新标记(CMS remark),修正并发标记阶段期间,因为工作线程继续运行而导致标记产生变动的那一部分对象的标记记录;

  4. 并发清除(CMS concurrent sweep),清理删除标记阶段判断为已经死亡的对象。

CMS 收集器存在以下三个明显的缺点:

  1. 对处理器资源非常敏感,CMS 默认启动的回收线程数是(核心处理数 + 3)/ 4;

  2. 无法处理浮动垃圾(Floating garbage);

  3. 产生大量的空间碎片。

Mixed GC

Garbage First 收集器

在 G1(Garbage First) 收集器出现之前的所有其它收集器,垃圾收集的目标范围要么是整个新生代(Minor GC),要么是整个老年代(Major GC),再要么就是整个 Java 堆(Full GC)。G1 可以面向堆内存里的任何部分来组成回收集(Collection Set,CSet)进行回收。

G1 不再以固定大小以及固定数量的分代区域划分,而是把连续的 Java 堆分成多个大小相等的独立区域(Region),每一个 Region 都可以根据需要被设置为新生代的 Eden 空间、Survivor 空间或者是老年代空间。G1 收集器能够对不同角色的 Region 采用不同的处理策略。

Region 中有一类特殊的 Humongous 区域,专门用来存储大对象的。G1 认为只要大小超过了一个 Region 容量的一般的对象,即可判定为大对象。每个 Region 的大小可以通过参数 -XX:G1HeapRegionSize 设定,取值范围为 1MB~32MB,且应是 2 的 N 次幂。对于那些超过了整个 Region 容量的超级大对象,将会被存放在 N 个连续的 Humongous Region 之中,G1 的大多数行为都会把 Humongous Region 作为老年代的一部分来进行看待。

G1 收集器能建立可预测的停顿时间模型,它将 Region 作为单次回收的最小单元,即每次收集的内存空间都是 Region 大小的整数倍。G1 收集器会跟踪各个 Region 中的垃圾堆积的「价值」大小,价值即回收所获得的空间大小以及回收所需要时间的经验值,然后维护一个优先级列表,每次根据用户设定的收集停顿时间(使用 -XX:MaxGCPauseMillis 指定,默认值是 200ms)优先处理回收价值收益最大的那些 Region,这也就是 Garbage First 名字的由来。

G1 收集器 使用 Region 划分内存空间,以及 具有优先级的区域回收方式,保证 G1 收集器在有限的时间内获得尽可能高的收集效率。

+-+-+-+-+-+-+-+-+-+-+
|E| | |S| | | | |E| |
+-+-+-+-+-+-+-+-+-+-+
| | | | | |E| | | | |
+-+-+-+-+-+-+-+-+-+-+
| | |E| | | |E| | |E|
+-+-+-+-+-+-+-+-+-+-+
|E| | | | | | | |E| |
+-+-+-+-+-+-+-+-+-+-+
| | |E| |E| | | | | |
+-+-+-+-+-+-+-+-+-+-+
| |S| | |S| | |H|H| |
+-+-+-+-+-+-+-+-+-+-+
| | | | | | | |H| | |
+-+-+-+-+-+-+-+-+-+-+
| | | | | |H| | | | |
+-+-+-+-+-+-+-+-+-+-+

最后更新于1年前