垃圾回收器和垃圾回收机制(简单介绍,用于回忆总结)

文章目录

  • 垃圾回收机制
    • [1. 分代收集](#1. 分代收集)
    • [2. 标记复制](#2. 标记复制)
    • [3. 标记清除](#3. 标记清除)
    • [4. 标记压缩(整理)](#4. 标记压缩(整理))
  • 垃圾回收器
    • [1. Serial / Serial Old](#1. Serial / Serial Old)
    • [2. Parallel Scavenge](#2. Parallel Scavenge)
    • [3. ParNew收集器](#3. ParNew收集器)
    • [4. CMS收集器](#4. CMS收集器)
    • [5. G1收集器](#5. G1收集器)
  • 参考链接

垃圾回收机制

1. 分代收集

  • 分代收集(Generational Collector )算法就是其中一种针对GC性能优化算法,将堆内存划分为新生代、老年代。
  • 在分代收集算法中,对象的存储具有以下特点:
    • 对象优先在 Eden 区分配。
    • 大对象直接进入老年代。
    • 长期存活的对象将进入老年代,默认为 15 岁。
  • 基本概念
    • 对象的生命周期:每经历一次GC,对象年龄 + 1。
    • 伊甸区:是对象诞生的地方。经过经验的推算,大部分对象的生命基本活不过1岁。
    • 生存区:活过了1岁,但大部分也活不到成年15岁。这些对象每经历一次 GC,会在 SA 和 SB 之间反复横跳。
    • 老年区:极少数成年的对象 或者 大对象会被一开始放在这儿。

2. 标记复制

  • 按内存容量将内存划分为等大小的两块。每次只使用其中一块,当这一块内存满后将尚存活的对象复制到另一块上去,把已使用的内存清掉。
  • 虽然实现简单,内存效率高,不易产生碎片,但是最大的问题是可用内存被压缩到了原本的一半。且存活对象增多的话,Copying算法的效率会大大降低。

3. 标记清除

  • 分为两个阶段:标注和清除。标记阶段标记出所有需要回收的对象,清除阶段回收被标记的对象所占用的空间。
  • 最大的问题是内存碎片化严重,后续可能发生大对象不能找到可利用空间的问题。

4. 标记压缩(整理)

标记后不是清理对象,而是将存活对象移向内存的一端。然后清除端边界外的对象。

垃圾回收器

1. Serial / Serial Old

  • Serial工作在新生代垃圾回收, Serial Old工作在老年代垃圾回收,一般作为CMS并发收集失败后的备选回收方案。
  • 当进行工作的时候,用户线程全部暂停,等它工作完成后,用户线程才允许继续工作。

简写: Serial收集器:全部暂停,直到收集结束。使用复制算法,响应速度快,没有线程交互开销,简单高效,额外内存消耗最小,适合用于单核cpu环境下client模式,体验会差一点,但只要不频繁发生收集,也可以接受。

2. Parallel Scavenge

  • ParNew收集器实质上是Serial收集器的多线程并行版本,除了同时使用多条线程进行垃圾收集之

    外,其余的行为包括Serial收集器可用的所有控制参数、收集算法、Stop The World、对象分配规则、回收策略等都与Serial收集器完全一致,在实现上这两种收集器也共用了相当多的代码。

  • 特点:

    • 多线程
    • STW相对少点
    • 关注吞吐量,高效率利用CPU

3. ParNew收集器

  • 和Parallel Scavenge收集器一样,都是多线程进行回收,不过主要是和CMS收集器配合使用

4. CMS收集器

  • CMS(Concurrent Mark Sweep)收集器是一种以获取最短回收停顿时间为目标的收集器。目前很大一部分的Java应用集中在互联网网站或者基于浏览器的B/S系统的服务端上,这类应用通常都会较为关注服务的响应速度,希望系统停顿时间尽可能短,以给用户带来良好的交互体验。CMS收集器就非常符合这类应用的需求。
  • 垃圾回收过程:
    • 初始标记initial-mark ):initial-mark 需要 Stop The World(简写为STW,就是停止所有用户线程),初始标记仅仅只是标记一下 GC Roots 能直接关联到的对象,速度很快。这个GC Roots 仅仅是老年代的 GC Roots ,同时初始标记不用去解决跨代引用(新生代引用老年代)问题,这个问题需要留在 remark 阶段去解决。暂停所有用户线程,只标记GC Roots直接引用的对象
    • 并发标记concurrent-mark):GC线程和用户线程同时工作,GC线程从gc goot开始遍历整个对象图
    • 重新标记remark ):remark 阶段需要 STW,这个阶段会比 initial-mark 阶段要长,但远比 concurrent-mark 阶段要短。主要是为了标记前面并发阶段,用户线程继续运作而导致漏标、少标的对象。
    • 并发清理concurrent-sweep ):concurrent-sweep 阶段不需要 Stop The World,上一阶段记录了本次 GC 的内存区域,标记整理算法并不用一一去回收已死对象,只需要把已死对象所在内存区域重新加入空闲列表即可。由于是和用户线程并发执行,这时新晋对象进入老年代所在的内存范围不在 GC 内存范围之内,所以它没被标记也不会被参与回收。
    • 并发重置concurrent reset):重新设置 CMS 相关的各种状态及数据结构,为下一个垃圾收集周期做好准备,将存活对象上的标记给移除掉,避免影响下次GC
  • 特点:
    • STW时间短
    • 产生浮动垃圾
    • 空间碎片(可以在清理后开启空间压缩处理)
    • 如果一直清理不干净,会导致频繁出现full GC最终导致并发收集失败,采用备选方案 Serial old单线程收集
  • CMS 很多阶段是和用户线程并发执行,这些阶段会源源不断有新的对象产生,从而触发 YGC,如果需要搬进老年代的对象大于老年代的可用空间,则会触发 Full GC。

5. G1收集器

  • Garbage First (简称G1)收集器是垃圾收集器技术发展历史上的里程碑式的成果,它开创了收集器面向局部收集的设计思路和基于Region的内存布局形式。全功能的垃圾收集器 ,主要面向服务端应用的垃圾收集器,具备较高吞吐率。

  • 调整:

    • 在新生代和老年代的基础上,加了一个存放大对象的区域
    • 将整个内存区域全部划分成大小相同的网格(region ),最多有2048个region
    • 每个region 都有可能存储新生代或老年代或大对象
    • 大对象的定义是超过region50%
    • 如果一个大对象存放不下,那么就跨越多个region存放
    • 可以通过参数控制停顿时间长短
  • 回收过程

    • 初始标记
    • 并发标记
    • 最终标记
    • 筛选回收
  • 特点

    • 并发和并行
    • 空间整合
    • 可预测的停顿

参考链接

CMS 垃圾回收器
G1垃圾回收器详解
JVM垃圾回收机制

相关推荐
ThisIsClark1 小时前
【后端面试总结】深入解析进程和线程的区别
java·jvm·面试
王佑辉2 小时前
【jvm】内存泄漏与内存溢出的区别
jvm
大G哥4 小时前
深入理解.NET内存回收机制
jvm·.net
泰勒今天不想展开4 小时前
jvm接入prometheus监控
jvm·windows·prometheus
东阳马生架构1 天前
JVM简介—3.JVM的执行子系统
jvm
程序员志哥1 天前
JVM系列(十三) -常用调优工具介绍
jvm
后台技术汇1 天前
JavaAgent技术应用和原理:JVM持久化监控
jvm
程序员志哥1 天前
JVM系列(十二) -常用调优命令汇总
jvm
黄油饼卷咖喱鸡就味增汤拌孜然羊肉炒饭1 天前
聊聊volatile的实现原理?
java·jvm·redis