垃圾回收算法

学习垃圾回收算法之前,我们先来了解一下Java中方法区的回收:

1.Java中方法区的回收主要收集两部分内容:废弃常量和无用的类
1)废弃常量:一般来讲,在垃圾回收时,没有被任何对象引用的常量将会被回收。
2)无用的类:只有同时满足一下三个条件才算是无用的类。

  • 该类的所有实例已经被回收
  • 加载该类的类加载器已经被回收
  • 该类的Class对象没有在任何地方被引用,无法在任何地方通过反射来获取该类的所有内容

接下来我们来看垃圾回收算法:

1.标记—清除算法:

  • 算法思想:根据名字其实就可以看出来,这个算法其实包含两部分,“标记"和"清除”。先标记出所有需要被回收的对象,然后再统一回收这些对象即可。
  • 缺点:这样的算法一方面效率不够高,另一方面会产生大量的不连续空间。

后续的这些垃圾回收算法其实都是对"标记—清除算法"的优化:

2.复制算法:又叫新生代回收算法

  • 算法思想:按照1:1的比例来划分内存空间,每次只使用一块这样的空间。当这块内存需要进行垃圾回收时,将这块内存上的所有存活的对象复制到另一块区域,然后将这块区域清理掉。
  • 优点:不会产生大量的不连续空间碎片,而且还能提高效率。
  • 缺点:由于新生代中大部分对象都是"朝生夕死"的,所以1:1来分配内存空间的方式,利用率并不高。

  • 优化:将内存空间按8:1的比例来进行划分。
    Eden:Survivor From:Survivor To = 8:1:1;
    具体过程:

  • 首先,将对象放置Eden区,当Eden区满时,会触发第一次gc,将还存活的对象复制到Survivor From区。
    在这里插入图片描述

  • 第二次触发gc的时候,扫描Eden和Survivor From区,将存活的对象复制到Survivor To区,然后清空扫描区。
    在这里插入图片描述

  • 第三次触发gc的时候,扫描Eden和Survivor To区,将存活的对象复制到Survivor From区,然后清空扫描区。
    在这里插入图片描述

  • 后续触发gc的时候,重复上述步骤。当一个对象在Survivor区中的From与To中来回复制交换15次后还是存活,则将此对象存入老年代。
    在这里插入图片描述

总结:
从上我们不难分析出,除了第一次,后续每次扫描的都是不为空的两块区域,然后将存活的复制到另一块为空的区域;当Survivor空间不够用时,需要依赖老年代进行分配大担保。

3.标记—整理算法:又叫老年代复制算法

  • 算法思想:与标记—清除类似,不同的是,在标记完所有要回收对象后,并不进行清除,而是让所有存活的对象向一端移动,最后清除存活区外的内存。
  • 优点:既不会产生大量的不连续空间碎片,也能提高效率。

了解了以上几种垃圾回收算法之后,我们就可以来看一下JVM所采用的"分代收集算法",其实这个算法就是根据对象存活周期的不同来采用不同的算法。

4.分代收集算法:
将Java堆分为新生代和老年代。

  • Minor GC:新生代GC,新生代对象大部分是朝生夕死的,所以采用复制算法。
  • Full GC:又叫Major GC或老年代GC,老年代中存活率较高,没有多余空间进行担保,所以采用"标记—整理"算法或"标记—清除"来进行垃圾回收。

垃圾回收算法其实是垃圾回收的方法论,而垃圾收集器就是内存回收的具体实现。以下是针对我们的垃圾回收算法所举例的垃圾收集器,博主只是了解:

  • 基于"标记—清除"的垃圾收集器:CMS老年代收集器,并发GC(用户线程与垃圾回收线程同时执行)
  • 基于"复制算法"的垃圾收集器:Parallel Scavenge新生代收集器,多线程收集器(多条垃圾回收线程并行处理)
  • 基于"标记—整理"算法的垃圾收集器:Parallel Old老年代收集器,多线程收集器

要注意的是,G1是唯一一款全区域的垃圾回收器,既能回收新生代,又能回收老年代。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值