JVM Knowledges-垃圾回收算法

本文介绍了几种常用的Java垃圾回收算法,包括Mark-Sweep(标记清除)、Copying(复制算法)、Mark-Compact(标记整理)和Generational Collection(分代收集)。讨论了各自的优缺点及其应用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文参考自周志明的《深入理解java虚拟机》,这本书写的非常好!非常推荐!

注意:各个平台的算法实现不尽相同。

1.Mark-Sweep算法(标记清除)

步骤:

  1. 首先标示需要清除的对象。

  2. 标记完成之后,统一回收掉被标记的对象。

缺点:

  1. 效率问题:标记清除过程效率都不高。

  2. 标记清除之后会产生大量的不连续的内存碎片。(空间碎片太多导致无法找到连续的空间用以分配较大的对象,而引起一次垃圾回收行为。)

2.Copying收集算法(复制算法)基于标记清除算法

步骤:

A.把可用内存划分为大小相等的两块。

B.每次使用其中一块。

C.当其中一块时候完的时候,就将还存活的对象复制到另外一块上去。

D.把已使用过的内存空间一次清理掉。

优点:

  1. 不必考虑内存碎片问题。

  2. 实现简单,运行高效。

缺点:

  1. 内存减少为原来的一半。

  2. 对象存活率较高的时候就要执行较多的复制操作。

  3. 如果不使用50%的对分策略,老年代需要考虑的空间担保策略。

演进:并不需要根据1:1划分内存空间,而是将内存划分为一块较大的EdenSpace和两块较小的SurvivorSpace

JavaHeap内存回收模型(当前商业虚拟机大多使用此算法回收新生代


3.Mark-Compact算法(标记整理算法)基于标记清除算法

由于复制算法的缺点,及老年代的特点(存活率高,没有额外内存对其进行空间担保),老年代一般不使用复制算法。

步骤:

  1. 标记不再使用的对象。

  2. 让存活的对象向内存的一段移动。

  3. 清理掉边界以外的内存。

由于老年代存活率高,没有额外内存对老年代进行空间担保,那么老年代只能采用标记-清理算法或者标记整理算法。

4.Generational Collection(分代收集算法)

 当前的商业虚拟机的垃圾收集都采用,把Java堆分为新生代和老年代。根据各个年代的特点采用最适当的收集算法。

Java所提倡的内存管理主要解决了两个问题:

  1. 给对象分配内存。

  2. 回收给对象分配的内存。

分配以及回收策略

  1. 大多数情况,对象在新生代的Edenspace分配。

  2. EdenSpace区没有足够空间进行分配时,虚拟机将发起一次MinorGC(Minor GC是指发生在新生代的垃圾回收动作。MajorFullGC是指发生在老年代的GC)

  3. 大对象(需要大量连续空间的Java对象)直接进入老年代。这样做避免了在EdenSpace和两个Survivor区之间发生大量的内存拷贝。

  4. 长期存活的对象将进入老年代。(生活在EdenspaceSurvivorSpace的对象经过MinorGC,确定年龄,到达一定年龄后晋升到老年代。

  5. 如果在SurvivorSpace中相同年龄的所有对象大小总和大于Survivor空间的一半。则年龄大于或等于该年龄的对象将直接进入老年代,而无需等待到达要求的年龄。

  6. 空间担保。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值