首页 > 编程知识 正文

新生代垃圾回收算法,四种垃圾回收算法

时间:2023-05-03 17:41:01 阅读:15773 作者:407

JVM垃圾回收算法的垃圾回收存储器布局必须理解垃圾回收算法。

在了解算法之前,先想想什么是垃圾吧? qfdfk不能用在我们身上。 它的存在对我们来说是多余的和徒劳的。

那么,在jvm中什么样的对象是垃圾呢? 在java中,通过引用与对象关联。 也就是说,要处理对象,必须通过引用进行。

如果不再引用对象,则必须回收该对象(垃圾)。

如何确定对象不再被引用? 在此引入一种叫做“引用计数器”的算法。 简单来说,如果引用了一个对象,则引用计数器将加1,反之则减1。 其参照计数为0时,被标记为垃圾。 其优点是简单高效,但无法解决循环引用问题。 因此,垃圾不会被回收。

为了解决“引用计数器”的弊端,java采用了“可达性分析法”:的方法。 该方法的基本思想是以一系列“GC路由”对象为起点进行检索。 应该注意的是,如果“GC路由”和一个对象之间没有可到达的路径,则该对象是不可到达的,但被确定为不可到达的对象不一定是可回收的对象。 被判断为不可到达的对象要成为可再利用的对象,至少要经过两次标记过程,如果在这两次标记过程中也无法避免成为可再利用的对象的可能性,基本上就成为真正可再利用的对象。

GC Roots •1,虚拟机堆栈中的本地变量可以引用的对象。

2、方法区域中静态属性引用的对象。

3、方法区域内的常量引用的对象。

4 .本地方法(朴素方法)中引用的对象。

5、虚拟机内部引用对象(类描述符、基本数据对应的类对象、异常对象)。

6、同步锁定中保持的所有对象。

7、描述虚拟机内部情况的对象(如JMXBean、JVMTI中注册的回调、本地缓存代码)。

8、垃圾回收引用的对象。

回收算法标志清除

复制标记

标记

分代收集

1 .打码去除打码方法是:首先确认打码对象是否生存,然后将死对象一并去除。

这是最基本的垃圾回收算法,最基本的是因为它最容易实现,思想也最简单。 标记-擦除算法分为两个阶段:标记阶段和擦除阶段。 标记阶段的任务是标记所有需要回收的对象,而清除阶段是回收标记对象占用的空间。

优点:容易实现,简单易行

缺点:

1.不连续空间 :

清除后,内存中会出现很多不连续的空间。 这是人们常说的空间碎片。 这样的空间碎片太多了,我们申请对象时申请空间很麻烦。 此外,当创建大对象时,由于存在可容纳的总空间,但空间不连续,因此无法分配对象。

2.不稳定 :

如果内存中的大量对象需要重用,标记和清理会花费时间,并且性能不稳定。

2 .标记复制为了解决美丽咖啡豆-Sweep算法的缺陷,提出了一种复制算法。 将可用内存按容量划分为两个大小相同的块,一次仅使用其中之一。 当此块的内存耗尽后,可以将仍然存在的对象复制到另一个块中,并一次清理已使用的内存空间,从而避免出现内存碎片问题。

标记复制方法将内存划分为三个区域,一个主区域用于创建新对象,两个复制区域用于存储生存对象。 这两个区域同时只使用一个,GC每次都将生存对象复制到另一个复制区域。 这将确保始终有连续的空白内存,并确保存储在下一个GC中生存的对象。

所有生存对象都被复制到新的可用内存空间中,因此所有对象存储都是连续的,而原始空间不必考虑保留生存对象,从而可以直接一次清除所有对象

优点:实现简单、高效、不易出现内存碎片

缺点:

1.会浪费一部分内存

从上图中可以看到,始终可用的内存空间不可用,也浪费了资源。

2.存活对象多会非常耗时

由于大多数对象都适用于已死亡的对象,因此如果大多数对象仍然存在,则表示复制标注的方法并不是很好,因为大多数对象都需要复制到其他区域。

3.需要担保机制

由于复制区域有空间浪费,因此为了减少浪费,将复制区域分配限制在较小的区间内。 如果存在很多对象,则复制区域中的空间可能不足以容纳这些对象。 如果是,请使用保证机制(

3 .为了解决标记整理Copying算法的缺陷,充分利用内存空间,提出了一种美丽的咖啡豆-Compact算法。 该算法的标记阶段与美丽的咖啡豆-Sweep相同,但标记完成后,将生存对象移动到一端,清理边缘边界以外的内存,而不是直接清理可重用对象

标记整理法是用另一种方法解决空间碎片的问题,对象被标记后,将生存的对象移动到存储器的另一侧,最后一并清除整理边界以外的区域,从而避免空间

碎片的产生。

优点 : 解决了上面的问题

缺点 :

1.整理过程时间比耗时

因为移动对象需要对其引用的地址进行变更,所以这个过程需要停止所有“用户线程”(也就是 stop the word ),从而造成应用程序的停顿,如果存活的对象越多那么迁移对象的过程时间就可能越长。

4.分代收集

分代收集算法是目前大部分JVM的垃圾收集器采用的算法。它的核心思想是根据对象存活的生命周期将内存划分为若干个不同的区域。一般情况下将堆区划分为老年代(Tenured Generation)和cqdse代(Young Generation),老年代的特点是每次垃圾收集时只有少量对象需要被回收,而cqdse代的特点是每次垃圾回收时都有大量的对象需要被回收,那么就可以根据不同代的特点采取最适合的收集算法。

目前大部分垃圾收集器对于cqdse代都采取复制算法,因为cqdse代中每次垃圾回收都要回收大部分对象,也就是说需要复制的操作次数较少,但是实际中并不是按照1:1的比例来划分cqdse代的空间的,一般来说是将cqdse代划分为一块较大的Eden空间和两块较小的Survivor空间,每次使用Eden空间和其中的一块Survivor空间,当进行回收时,将Eden和Survivor中还存活的对象复制到另一块Survivor空间中,然后清理掉Eden和刚才使用过的Survivor空间。

而由于老年代的特点是每次回收都只回收少量对象,一般使用的是标记-整理算法(压缩法)。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。