概述

垃圾收集器主要是用于JVM内存中的垃圾回收

垃圾收集器针对不同的算法有不同的实现

GC Root的对象有:

  • 虚拟机栈中引用的对象(本地变量表)
  • 方法区中静态属性引用的对象
  • 方法区中常量引用的对象
  • 本地方法栈中引用的对象(Native对象)

垃圾收集算法

标记-清除算法

分为两个阶段: 先标记,后清除

首先标记出所有需要回收的对象,然后统一清除被标记的对象

缺点:

  1. 效率不高
  2. 产生大量不连续的内存碎片

复制算法

标记-清除算法的升级版。

分为三个阶段:标记、复制、清除

将可用的内存分成大小相等的两块,每次只是用其中的一块内存,当这块内存满后,就把还存活的对象复制到另外一块上面,然后清除这一整块的内存空间

优点:

  1. 效率高
  2. 不会产生大量连续的碎片

缺点:

  1. 空间的利用率不高

标记-整理算法

标记-清除算法的升级版。

分为三个阶段:标记、整理、清除

先标记出所有需要回收的对象,将所有存活的对象移动到一端,然后直接把边界意外的内存清空即可

优点:

  1. 不会产生大量连续的内存碎片

分代收集算法

将java堆分成新生代和老年代,可以根据各个年代中对象存活周期来选择最合适的收集算法

新生代:由于只有少量的对象能存活下来,所以选用 复制算法(只需要付出少量存活对象的复制成本)

老年代,由于对象的存活率高,没有额外的空间分担,就必须使用 标记-清除算法标记-整理算法

垃圾收集器种类

java堆内存被划分为 新生代年老代两部分

新生代主要使用 复制算法 年老代主要使用 标记-整理算法标记-清除算法(CMS)

在java虚拟中针对 新生代年老代分别提供了多种不同的垃圾收集器,JDK1.6中Sun HotSpot虚拟机的垃圾收集器如下

垃圾收集器分类-2020-08-31-14:43:20.png

如果两个垃圾收集器直接有连线,则表明这两个垃圾收集器可以搭配使用

新生代垃圾收集器

Serial

使用 复制算法,单线程

垃圾收集时需要暂停其他所有的工作线程


Serial垃圾收集器可以和老年代的 Serial OldCMS配合使用

Serial/ Serial Old收集器运行示意图:

Serial与Serialold配合使用过程-2020-08-31-14:43:50.png

ParNew

使用 复制算法,是Serial的多线程版本,默认的新生代垃圾收集器

收集器默认开启和CPU数目相同的线程数

垃圾收集时需要暂停其他所有的工作线程


ParNew垃圾收集器可以和老年代的 Serial OldCMS配合使用

ParNew/ Serial Old收集器运行示意图:

ParNew与Serialold配合使用过程-2020-08-31-14:44:12.png

Parallel Scavenge

使用 复制算法,多线程

它重点关注的是程序达到一个可控制的吞吐量

吞吐量:运行用户代码时间/(运行用户代码时间+垃圾收集时间))

高吞吐量可以最高效率地利用CPU时间,尽快地完成程序的运算任务,主要适用于在后台运算而不需要太多交互的任务


Parallel Scavenge垃圾收集器可以和老年代的 Serial OldParallel Old配合使用

老年代垃圾收集器

CMS

全称为Concurrent Mark Sweep

最主要目标:获取最短垃圾回收停顿时间

使用 标记-清除算法(和其他老年代收集器的算法不同),多线程

他能够让垃圾收集线程和用户线程同时工作,主要分为4个阶段:

  1. 初始标记:只是标记一下GC Roots能直接关联的对象,速度很快,仍然需要暂停所有的工作线程。
  2. 并发标记:进行GC Roots跟踪的过程,和用户线程一起工作,不需要暂停工作线程。
  3. 重新标记:为了修正在并发标记期间,因用户程序继续运行而导致标记产生变动的那一部分对象的标记记录,仍然需要暂停所有的工作线程(但是时间短,主要特点)
  4. 并发清除:清除GC Roots不可达对象,和用户线程一起工作,不需要暂停工作线程。

CMS收集器工作过程:

CMD工作过程-2020-08-31-14:44:27.png


缺点:

  1. 对CPU资源非常敏感,其默认启动的收集线程数=(CPU数量+3)/4,如果CPU负荷已经比较高的情况下,如果还要分出CPU资源用来运行垃圾收集器线程,会使得CPU负载加重
  2. CMS无法处理浮动垃圾,可能会导致另一次Full GC,由于CMS收集器和用户线程并发运行,因此在收集过程中不断有新的垃圾产生,这些垃圾出现在标记过程之后,CMS无法在本次收集中处理掉它们,只好等待下一次GC时再将其清理掉,这些垃圾就称为浮动垃圾。
  3. 基于标记-清除算法,因此不可避免会产生大量不连续的内存碎片,如果无法找到一块足够大的连续内存存放对象时,将会触发因此Full GC。

因为CMS收集器采用的是 标记-清除算法,所以CMS可以和老年代Serial Old配合使用,也可以将自己作为老年代收集器,与新生代的ParNew收集器配合使用

Parallel Old

使用 标记-整理算法,多线程

为了在年老代同样提供 吞吐量优先的垃圾收集器

如果系统对吞吐量要求比较高,可以优先考虑新生代Parallel Scavenge和年老代Parallel Old收集器的搭配策略。

新生代Parallel Scavenge和年老代Parallel Old收集器搭配运行过程图:

ParallelScavenge和Parallelold收集过程-2020-08-31-14:44:55.png


Parallel Old垃圾收集器可以所有新生代的垃圾收集器配合使用

Serial Old(MSC)

使用 标记-整理算法,单线程,默认的老年代垃圾收集器

新生代Serial与年老代Serial Old搭配垃圾收集过程图:

Serialold收集器工作原理-2020-08-31-14:45:35.png


Serial old收集器可以和新生代的Parallel Scavenge垃圾收集器配合使用

新一代垃圾收集器

G1

全称为Garbage First

目前垃圾收集器理论发展的最前沿成果,G1收集器两个最突出的改进是:

  1. 基于记-整理算法不产生内存碎片
  2. 可以非常精确控制停顿时间,在不牺牲吞吐量前提下,实现低停顿垃圾回收。

原理: G1收集器避免全区域垃圾收集,它把堆内存划分为大小固定的几个独立区域,并且跟踪这些区域的垃圾收集进度,同时在后台维护一个优先级列表,每次根据所允许的收集时间,优先回收垃圾最多的区域

分和优先级区域回收机制,确保G1收集器可以在有限时间获得最高的垃圾收集效率


G1收集器运行示意图:

G1的收集过程-2020-08-31-14:46:25.png

0条评论
头像
ICP证 : 浙ICP备18021271号