Arnold's Blog Arnold's Blog
🏠首页
  • Java
  • Python
💻前端
🕸️周边技术
🗒️札记
  • Tips
  • 读书
  • 友情链接
🧑‍💻关于
🔖收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

Arnold Shu

知人者智,自知者明。胜人者有力,自胜者强。
🏠首页
  • Java
  • Python
💻前端
🕸️周边技术
🗒️札记
  • Tips
  • 读书
  • 友情链接
🧑‍💻关于
🔖收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • Java

    • Java注解以及自定义注解
    • 函数式编程(JAVA)
    • 记一次GC 排查及优化
    • JVM浅析总结(JVM的生命周期)
    • JVM浅析总结(类加载器)
    • JVM浅析总结(运行时数据区)
    • JVM浅析总结(执行引擎)
    • JVM浅析总结(垃圾回收)
      • 垃圾回收(GC)
        • 垃圾回收相关算法
        • 垃圾回收器
    • JVM浅析总结(Class文件结构)
    • JVM浅析总结(JAVA监控与调优工具)
    • 程序设计中SPI和API
  • Python

  • Spring

  • SpringBoot

  • backend
  • Java
Arnold Shu
2021-11-17
目录

JVM浅析总结(垃圾回收)

# 垃圾回收(GC)

垃圾的定义:运行程序中没有任何指针指向的对象

# 垃圾回收相关算法

  • 垃圾标记阶段算法(对象存活判断,对象死亡定义:不再被任何存活对象继续引用时,就宣布死亡)
算法名称 算法详情 优点 缺点
引用计数算法(Reference Counting) java并没有采用该算法,对每一个对象保存一个整数的引用计数器属性,用于记录对象被引用的情况 实现简单,垃圾对象便于标识,判断效率高,回收没有延迟性 存储计数器,增加内存开销,每次赋值都需增减,增加了时间开销,无法处理循环引用的情况
可达性分析算法(Tracing Garbage Collection 根搜索算法,追踪性垃圾收集) 以根对象集合(GC Roots)为起点,按照从上至下的方式搜索跟对象集合所连接的目标对象是否可达,搜索所走过的路径为引用链(Reference Chain),如果没有任何应用链相连,则是不可达,可标记为垃圾对象 实现简单,垃圾对象便于标识,判断效率高,解决了循环引用
  • 垃圾清除阶段算法
算法名称 算法详情 优点 缺点
标记-清除算法(Mark-Sweep) 堆中可用内存不足,停止整个程序(stop the world),然后标记从引用根节点开始遍历,收集器标记所有引用的对象,在header中记录为可达对象,收集器对堆内存从头到尾进行线性遍历,发现对象Header中没有标记为可达对象的,将其回收 基础常见 效率不高,发生stw,内存不连续,且维护空闲列表
复制算法(Copying) 将活着的内存空间分为两块,每次只使用其中的一块,在垃圾回收时将正在使用的内存中的对象(活着的对象)复制到未使用的内存块中,之后清除正在使用的内存块中的所有对象(活着的对象+垃圾对象),交换两个内存的角色,最后完成垃圾回收 没有清除标记步奏更高效,复制对象保证空间连续性 需要更大的内存空间,空间浪费,G1垃圾回收器指针引用关系内存占用以及时间开销大
标记-压缩算法(Mark-Compact) 第一阶段和标记清除算法一样,从根节点开始标记所有被引用对象,第二阶段将所有存活对象压缩到内存的一端,按顺序排放,之后清除边界外所有的空间 消除标记-清除算法中内存碎片的问题,消除了复制算法的内存double开销 效率低于复制算法,移动对象被其他引用,则还需要调整引用,stw事件
分代收集算法(Generational Collecting) 结合分代在各个代上使用上述三种算法
增量收集算法(Incremental Collecting) 垃圾收集线程和引用线程交替执行,每次只收集一小片区域的内存空间,接着切换到应用线程交替执行,以此反复,直到垃圾全部收集完成 任然是以标记-清除和复制算法为基础,清除stw事件 线程切换和上下文切换的消耗,系统吞吐量下降
分区算法(Incremental Collecting) 堆空间划分为多个小块,根绝目标的停顿事件,合理的回收若干个小区间,从而减少gc的停顿

# 垃圾回收器

垃圾回收器分类

分类 详情
按线程分 串行垃圾回收器(Serial(新生代),Serial Old(老年代)),并行垃圾回收器(ParNew(新生代),Parallel Scavenge(新生代),Parallel Old(老年代))
按工作模式分 并发式垃圾回收器(CMS(老年代),G1(整堆收集器)),独占式垃圾回收器(stw)
按碎片处理方式分 压缩式垃圾回收器,非压缩式垃圾回收器
按工作的内存区间分 年轻代垃圾回收器,老年代垃圾回收器

经典回收器详情

垃圾器 详情 优势
Serial 最基本历史最悠久的垃圾回收器,jdk1.3之前回收新生代的唯一选择,作为HotSpot中client模式下的默认新生代垃圾收集器,采用了复制算法,串行回收和stw机制的方式执行内存回收 单线程下简单而高效
Serial Old 老年代垃圾回收,同样采用串行回收和stw机制,回收内存算法用的是标记-压缩算法,client模式下的默认老年代垃圾收集器,server模式下,可与新生代的Parallel Scavenge配合使用,也可作为CMS收集器的后备垃圾收集方案 单线程下简单而高效
ParNew 与Serial几乎没有差别,同样采用了复制算法,并行回收和stw机制的方式执行内存回收 ,除了Serial,目前只有ParNew能与CMS收集器配合工作 多cpu下比Serial高效
Parallel Scavenge 与ParNew几乎没有差别,同样采用了复制算法,并行回收和stw机制的方式执行内存回收 ,可控制的吞吐量(吞吐量优先),自适应调节策略 多cpu下比Serial高效
Parallel Old 替代Serial Old收集器,采用了标记-压缩算法,并行回收和stw机制的方式执行内存回收 多cpu下比Serial高效
CMS(Concurrent-Mark-Sweep) 采用了标记-清除算法,真正意义的并行回收和stw机制的方式执行内存回收 垃圾回收线程与用户线程同时工作,停顿时间短,响应速度块,低延迟
G1(Garbage First) 作为jdk9 的默认垃圾回收器,取代CMS以及Parallel +Parallel Old的组合,G1将内存划分未一个个的region,内存回收以region为基本单位,region之间采用的是复制算法,整体上可看作标记压缩算法,避免内存碎片化 并行并发,分代收集,空间整合,可预测停顿模型,G1的内存占用以及执行负载都比CMS高,在小内存应用上CMS的表现大概率由于G1,G1在大内存应用上具有优势,平衡点在6-8G之间

尚硅谷图片 在这里插入图片描述

#JVM#GC
上次更新: 2023/12/18, 13:54:07
JVM浅析总结(执行引擎)
JVM浅析总结(Class文件结构)

← JVM浅析总结(执行引擎) JVM浅析总结(Class文件结构)→

最近更新
01
《领域驱动设计:软件核心复杂性应对之道》书摘
12-26
02
Linux 的常用命令
10-22
03
程序设计中SPI和API
10-22
更多文章>
Theme by Vdoing | Copyright © 2017-2024 Arnold Shu | CC BY-SA 4.0 License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式