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

文章目录

  • 垃圾回收机制
    • [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垃圾回收机制

相关推荐
程序猿20231 天前
MAT(memory analyzer tool)主要功能
jvm
期待のcode1 天前
Java虚拟机的非堆内存
java·开发语言·jvm
jmxwzy1 天前
JVM(java虚拟机)
jvm
Maỿbe1 天前
JVM中的类加载&&Minor GC与Full GC
jvm
人道领域1 天前
【零基础学java】(等待唤醒机制,线程池补充)
java·开发语言·jvm
小突突突1 天前
浅谈JVM
jvm
饺子大魔王的男人1 天前
远程调试总碰壁?局域网成 “绊脚石”?Remote JVM Debug与cpolar的合作让效率飙升
网络·jvm
天“码”行空2 天前
java面向对象的三大特性之一多态
java·开发语言·jvm
独自破碎E2 天前
JVM的内存区域是怎么划分的?
jvm
期待のcode2 天前
认识Java虚拟机
java·开发语言·jvm