垃圾回收算法及经典的垃圾收集器

1、垃圾回收算法

1.1 分代收集理论

        大多数的垃圾收集器都遵循“分代收集”,建立在两个分代假说之上

  1. 弱分代假说:绝大多数对象都是朝生夕灭的
  2. 熬过越多次垃圾收集过程的对象就越难消亡

        将Java堆划分出不同的区域,将回收对象根据其年龄分配到不同的区域中存储,垃圾收集器每次只需要回收一部分区域

-局部收集:不完整收集整个Java堆,只收集其中一部分
	新生代收集(Minor GC/Young GC):收集新生代
	老年代收集(Major GC/Old GC):收集老年代
	混合收集(Mixed GC):收集整个新生代以及部分老年代,只有G1收集器才会有这种行为
整堆收集(Full GC):整个Java堆和方法区的收集

1.2 垃圾回收算法

  1. 标记-清除算法
**过程**:标记出所有需要回收的对象,在标记完成后,统一回收掉所有被标记的对象。
     标记过程属于垃圾的判定过程‘
**缺点**:
			1、**执行效率不稳定**,标记和清除两个过程的效率随着对象数量的增长而降低
			2、**内存碎片化问题**,标记清除过后产生大量不连续的碎片,如果在后续的程序运行过程中无法找到连续的内存,就不得不提前触发另一次垃圾收集动作
		
  1. 标记-复制算法
            回收新生代的算法,新生代的对象朝生夕灭,每次GC存活的对象比较少,所以需要复制的对象也比较少,采用该算法效率比较高
**过程**:将内存分为两个区域,每次只使用其中一块区域,每次GC,将该区域中存活的对象复制到另一块区域中。
**优点**:垃圾回收过程不会产生空间碎片
**缺点**:减小了可用内存

Serial和ParNew两种新生代收集器均采用该算法

  1. 标记-整理算法
            回收老年代的算法
**过程**:让所有存活对象都向内存空间一端移动,直接清除掉边界以外的内存。移动过程中需要暂停全部用户应用程序才能进行

2、垃圾回收器

在这里插入图片描述

  • 新生代的垃圾收集器均采用标记-复制算法

新生代收集器

2.1 Serial 与ParNew

ParNew 是 Serial的多线程并行版本
二者在收集的时候均需要Stop the World
二者都可与CMS配合使用
Serial是客户端的默认垃圾收集器,ParNew是服务器端的默认垃圾收集器

2.2 Parallel Scavenge

目标:达到一个可控制的吞吐量,吞吐量优先收集器

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

1. 手段
        提供两个参数用于精确控制

-XX:MaxGCPauseMillis:保证内存回收花费的时间不超过用户设定值
-XX:GCTimeRatio:垃圾回收时间的总比率

2. 与ParNew的区别

  1. ParNew的关注点是尽可能是缩短垃圾收集时用户线程的停顿时间,Parallel Scavenge的关注点为达到一个可控制的吞吐量
  2. Parallel Scavenge可以采用自适应调节策略,不需要人工指定新生代的大小,Eden与Survivor的比例,晋升老年代对象年龄大小等细节参数,系统会根据性能监控信息动态调整这些参数以提供最合适的停顿时间或者最大的吞吐量。-XX:+UseAdaptiveSizePolicy

老年代收集器

1. Serial Old 与Parallel Old

  1. Serial Old是Serial的老年代版本,Parallel Old是Parallel Scavenge的老年代版本
  2. Serial 为客户端的收集器,Parallel Old是服务器端的收集器

2. CMS(Concurrent Mark Sweep)

         第一款支持并发的垃圾收集器
目标:获取最短回收停顿时间

过程:
     初始标记:标记GC Roots直接关联的对象,Stop the World
     并发标记:从GC Roots直接关联的对象开始遍历整个对象图的过程中
     重新标记:修正并发标记期间因用户程序继续运作而导致标记产生变动的那一部分对象的标记记录,Stop the World
     并发清除:清除标记阶段已经死亡的对象

整个过程耗时最长的是并发标记和并发清除的过程,但是都可以与用户线程一起工作

缺点:

1、**对处理器资源非常敏感**。在并发阶段,虽然不会导致用户线程停顿,但是却占用了处理器的计算能力,使应用程序变慢
2、**无法处理浮动垃圾**。在并发标记和并发清除阶段用户程序还在运行,新的垃圾不断产生,但是这部分垃圾对象的出现是在标记过程结束以后,所以CMS无法在当次收集中处理,只有留在下一次GC时处理。CMS 不会等到老年代几乎填满进行GC,而是预留了一部分空间,预留的空间太小,可用内存变小,预留的空间太大,可能会导致无法满足新对象的分配,出现一次“并发失败”,启动Serial Old进行老年代收集
3、采用标记-清除算法,产生大量空间碎片

G1收集器

        服务端的垃圾收集器,不再像传统的回收新生代、老年代,而是Mixed GC,哪块内存中存放的垃圾数量最多,回收收益最大,就回收哪一块

        G1不再坚持固定大小以及固定数量的分代区域划分,而是把连续的Java堆划分成多个大小相等的独立区域(Region),每一个区域根据需要,扮演新生代的Eden、Survivor空间或者老年代空间。收集器能够根据不同角色的Region采用不同策略处理
        一类特殊的Humongous,专门用来存储大对象,只要一个对象超过一个Region容量的一半,就认为是大对象
        新生代和老年代不再需要是固定的,而是一系列区域的动态集合。G1将Region作为单次回收的最小单元。 G1会跟踪各个Region里面的垃圾堆积的价值大小,价值即回收所获得得空间大小以及回收所需时间的经验值,然后再后台维护一个优先级列表,每次在用户允许的收集停顿时间,优先处理回收价值收益最大的那些Region。

过程

1、初始标记:
2、并发标记:
3、最终标记:
4、筛选回收:

具体的可以看这篇博客https://www.jianshu.com/p/548c67aa1bc0

G1和CMS 的对比

G1的优点:

  1. 可以指定最大停顿时间、分Region的内存分布、按收益动态确定回收区域
  2. 没有采用标记-清除算法,不会产生空间碎片

G1的缺点:

  1. CMS只用维护一个卡表,但是G1的每个区域都要维护一个卡表,G1会有更多的内存负担和维护开销

CMS

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值