垃圾回收算法分析与JVM具体应用

JVM中一般使用标记清除、标记复制、标记整理这3种垃圾回收策略。

垃圾回收的目的就是回收程序不再使用的对象所占用的内存空间,其过程涉及:垃圾判定、垃圾清除、内存整理等问题。

标记-清除

我们首先介绍标记清除算法,因为这是一种最基础的垃圾回收算法,它的回收过程主要分为两个阶段:1、根据可达性分析算法,标记每一个存活的对象,2、将没有被标记的对象作为垃圾对象进行回收。当然也可以反过来标记。

回收之前内存状态

在这里插入图片描述
回收之后内存状态

在这里插入图片描述

优点:

1、整个回收过程只需要简单的设置一个标记位,相对而言开销较小,能实现较高的吞吐量。
2、整个回收过程不会移动存活的对象。
3、相比复制算法,内存利用率高。

缺点:

1、 执行效率不稳定,如果标记的是存活对象,那么存活对象较多时就需要大量的标记和清除,如果标记的是可回收对象,那么可回收对象较多时就需要大量的标记和清除。
2、内存碎片问题,从上图中也可以看出,再一次回收完成后内存未使用空间看起来依然很零碎,这样将导致大对象因为没有连续的内存空间而无法被分配。

标记-复制

使用标记复制算法当存活对象较少时的可以得到不错的收益,基本的算法思想是将内存分为两个大小相等的区域,分配对象时每次只使用其中的一块区域,当这块区域用完时,就把还存活的对象复制到另一块区域上,然后再把这块区域已使用的空间直接清除。

回收之前内存状态

在这里插入图片描述
回收之后内存状态

在这里插入图片描述

优点:

1、如果大部分对象都是可回收的,那么只需要复制少量存活的对象,效率较高。
2、不存在内存碎片的问题。
3、分配对象简单,只需移动堆顶指针,按顺序分配即可。

缺点:

1、内存利用率较低,需要空出一半的内存空间用来确保容得下存活的对象。
2、存活对象在内存中的位置会发生变化,需要移动对象的引用地址。
3、同样只适合存活对象较少的场景,如果存活对象较多就会复制大量的存活对象。

标记-整理

标记整理算法同时解决了标记清除的内存碎片问题和标记复制的内存浪费的问题,相比标记清除算法,标记整理多个一步整理阶段,即移动存活对象,让存活对象向堆的一端移动,然后再清理掉其余的内存空间。

回收之前内存状态

在这里插入图片描述
回收之后内存状态

在这里插入图片描述

优点:

1、解决了内存碎片的问题。
2、解决复制算法的内存浪费的问题。

缺点:

1、同样如果存活对象较多,每次移动存活对象又会带来不小的开销。

JVM中的具体应用

通过上面的分析我们了解到,每种垃圾收集器都有一定的适用范围,所以在JVM中并没有完全的采用其中任意一种垃圾回收算法,而是根据不同的场景选择合适的算法。

分代收集

为了满足选择合适的垃圾回收算法,JVM中采用了分代收集的理论进行设计,它建立在两个分代假设之上:

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

基于这两个假设的基础上,JVM对堆空间进行了划分,并根据对象的年龄(熬过多次的对象)划分到不同的空间上,所以就划分出了:新生代、老年代。

新生代:基于弱分代假说理论,大多数对象都是可回收的,所以可以采用标记复制算法。
老年代:基于强分代假说理论,把在新生代经历过多次回收都存活的对象,放入老年代,那么老年代中的对象大部分就都是不可回收的,所以可以采用标记清除或者标记整理算法,只需要少量的标记和清除可回收对象即可。

同时新生代中的对象因为死的快,而老年代中的对象大多数都是难以消亡的,所以把这个两部分区域划分开来,就又能以不同回收频率去进行回收,老年代的回收频率往往要远低于新生代的回收频率。

标记复制算法的改进

现在我们知道新生代可以采用标记复制算法进行回收,而标记复制算法的缺点就是需要空出一半的内存空间,那么在JVM中实际上并没有这样做,IBM公司曾有一项专门研究对新生代“朝生夕灭”的特点做了更量化的诠释——新生代中的对象有98%熬不过第一轮收集。因此并不需要按照1∶1的比例来划分新生代的内存空间。

依据这一项研究,HotSpot虚拟机又把新生代划分为了3个部分:Eden、Survivor0、Survivor1,他们的比例默认为8:1:1,也就是说两个Survivor区采用完全复制的算法,这样一来仅仅浪费了新生代的10%的内存空间。

当然理论之下总有意外,如果存活的对象就是超过了10%怎么办?当然这时候一般就会依靠老年代来进行担保了。

标记清除还是标记整理?

HotSpot中关注吞吐量的Parallel Scavenge收集器是基于标记整理算法的,而关注延迟的CMS收集器则是基于标记清除算法的。

为什么Parallel Scavenge选择标记整理,CMS选择标记清除?

标记清除和标记整理的主要区别就在于对象的移动整理,如果移动则内存回收时会更加复杂,如果不移动则对象分配时会更加复杂,所以标记清除算法在垃圾回收时速度更快、停顿时间更短,而标记整理算法虽然停顿时间稍长,但是对象的分配和访问则相比标记清除更加快,又因为分配和访问的频率要远远高于垃圾回收的频率,所以从总比来看吞吐量是要高于标记清除算法的。

CMS中还有一种特殊的做法,就是一般情况下采用标记清除算法,直到碎片程度太严重的时候可以再采用标记整理算法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码拉松

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值