垃圾收集器算法介绍

垃圾收集器算法是指在Java虚拟机中用于执行垃圾回收的具体算法。Java虚拟机提供了多种垃圾收集器算法,每种算法都有其特点和适用场景。

1. 标记-清除算法(Mark and Sweep):这是最基本的垃圾收集算法。它分为两个阶段:标记阶段和清除阶段。首先,垃圾收集器会从根对象开始遍历,标记所有可达的对象。然后,在清除阶段,垃圾收集器会清除未被标记的对象,释放其占用的内存空间。标记-清除算法的缺点是会产生内存碎片。

以下是标记-清除算法的简单示意图:

+------+      +------+      +------+      +------+  
|  未清除  |----|  标记  |----|  清除  |----|  未清除  |  
+------+      +------+      +------+      +------+  
     ^                                       |  
     |                                       v  
     清除旧的标记                         创建新的对象  
     创建新的对象                         清除旧的标记

标记-清除算法由两部分组成:标记和清除。在标记阶段,算法会遍历所有对象,将所有可达对象标记为“存活”状态,而不可达对象则被标记为“未清除”状态。在清除阶段,算法会释放未清除对象所占用的内存空间,以便垃圾回收器可以将其重新利用。

该算法存在一些问题。首先,由于标记和清除两个阶段是分离的,因此在标记阶段结束后到清除阶段开始前这段时间内,未标记为存活的对象将继续占用内存空间。这可能会导致内存占用率较高。其次,由于需要遍历所有对象并进行标记和清除操作,因此该算法的时间复杂度为O(n),其中n是所有对象的数量。这可能会影响应用程序的性能。最后,由于该算法只关注内存占用情况而忽略其他资源的使用情况,因此可能会导致资源浪费问题。

2. 复制算法(Copying):复制算法将内存分为两个相等大小的区域,通常称为"From"区和"To"区。在垃圾收集过程中,所有存活的对象都会被复制到"To"区,然后清空"From"区。复制算法的优点是简单高效,但缺点是只能使用堆内存的一半。

复制算法主要应用于新生代,它将内存分为两个区域,每次只使用其中一个。当一个对象在Eden区被创建并且Eden区满时,会触发GC。这时,如果对象仍然存活,它们会被复制到另一个空闲的内存区域(例如From区域或To区域)。这个过程分为两步:

  • 当Eden区满时,JVM会停止应用程序的运行,并开启复制算法的GC线程。该线程将所有存活的对象复制到另一块空闲的内存空间(假设是To区域)。在复制完成后,Eden区和From区域将被清空。
  • GC线程会更新所有存活对象的内存引用地址,使它们指向新的内存地址。在复制完成后,会把使用过的空间一次性清理掉。这样,每次的内存回收都是对内存空间的一半进行回收。

以上就是复制算法的工作过程。希望这对您有所帮助。

3. 标记-整理算法(Mark and Compact):标记-整理算法结合了标记-清除算法和复制算法的优点。它首先进行标记阶段,标记所有可达的对象。然后,在整理阶段,它会将存活的对象向一端移动,并清理掉边界以外的内存空间。标记-整理算法解决了标记-清除算法产生的内存碎片问题。

标记-整理算法主要应用于老年代。该算法在标记阶段与标记-清除算法相似,它会遍历所有对象并标记所有存活对象。然而,在标记完成后,标记-整理算法并不会立即清除未标记的对象,而是将所有存活对象移动到内存的一端,并将所有引用它们的指针更新为新的内存地址。然后,算法会清理掉边界以外的内存空间,这样就不会产生内存碎片。

这种算法在一定程度上弥补了标记-清除算法和复制算法的缺点。它避免了内存空间碎片的问题,提高了内存的利用率。然而,它也有更高的使用成本,因为它需要标记所有存活对象,并进行对象的移动和引用地址的更新操作。

4. 分代收集算法(Generational):分代收集算法基于一个观察:大部分对象的生命周期较短。根据这个观察,分代收集算法将内存分为不同的代,通常是新生代和老年代。新生代中的对象生命周期短,因此使用复制算法进行垃圾回收。老年代中的对象生命周期长,因此使用标记-清除或标记-整理算法进行垃圾回收。

分代收集算法是大多数虚拟机垃圾收集器采用的算法,主要根据对象的存活周期将Java堆内存划分为几块,即新生代区域和老年代区域,然后对不同的区域采用合适的算法。

  • 在新生代每次GC时,由于大量对象死去,只有少量对象存活,因此通常选用复制算法,将存活的对象复制到另一块空闲的内存空间。在复制完成后,清空当前内存区域,为新的对象分配内存。
  • 在老年代中,由于存活率高、没有额外空间对它进行分配担保,就必须使用标记-清理或标记-整理算法进行回收。在标记阶段,算法会遍历所有对象并标记所有存活对象;在清理阶段,算法会清理掉未被标记的内存空间,回收其内存。

5. 并行和并发收集算法(Parallel and Concurrent):并行收集算法使用多个线程并行执行垃圾回收操作,以提高垃圾回收的效率。并发收集算法则是在程序运行的同时执行垃圾回收操作,减少垃圾回收对程序执行的影响。

在并发收集算法中,虽然有多个垃圾收集线程,但它们在收集垃圾时,不会相互干扰。每个线程只关注自己的分代区域进行垃圾收集,同时操作系统负责将有限的 CPU 资源分配给不同的任务。通过将 CPU 的使用权在恰当的时机分配给不同的任务,使得多个任务在视觉上看起来是一起执行的。因为CPU切换的速度极快,所以用户根本感受不到任务的切换。

在并行收集算法中,同样也有多个垃圾收集线程,但是与并发收集算法不同的是,它们会同时执行。这大大提高了垃圾收集的速度和效率。

需要注意的是,Java虚拟机通常会根据当前的运行环境和垃圾收集的需求自动选择合适的垃圾收集器算法。开发人员也可以通过参数配置来指定使用特定的垃圾收集器算法。

综上所述,垃圾收集器算法包括标记-清除、复制、标记-整理、分代收集、并行和并发等多种算法。每种算法都有其优缺点和适用场景,Java虚拟机会根据实际情况选择合适的算法来执行垃圾回收。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值