欢迎光临车床网站,为您提供精密加工全套工艺生产线

【永康市二手机床回收】垃圾回收器常用算法

作者:以沫      发布时间:2021-04-12      浏览量:0
引用计数法(reffrenceCouti

引用计数法(reffrenceCoutin.

引用计数器的实现??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????对象a的引用计数器的值为0的话,对象a就不能再使用了。

引用计数器的实现也非常简单,只需要为每个对象配置一个整形的计数器即可。然而,引用计数器存在一个严重的问题,即无法处理循环引用。因此,Java的垃圾回收器没有使用这种算法。

简单的循环引用问题描述如下:对象a和对象b,对象b中包含对象b的引用,对象b中包含对象a的引用。这时,对象A和对象B的引用计数器不是0。但是,系统中没有任何第3位的对象。也就是说,a和b是应该回收的垃圾对象,但垃圾对象之间相互引用,垃圾回收器无法识别,内存泄漏。

标记-清除算法

标记-清除算法将垃圾回收分为标记阶段和清除阶段。一个可行的实现是,在标记阶段首先通过根节点,标记所有从根节点开始的大对象。因此,未标记的对象是未引用的垃圾对象。然后,在清除阶段,清除所有未标记的对象。这种算法最大的问题是存在大量的空间碎片,因为回收后的空间片。在对象堆积空间分配过程中,特别是大对象的存储器分配,不连续存储器空间的生产效率低于连续空间。

复制算法

将现有存储空间分为两个快速,每次只使用其中一个,垃圾回收时将使用的存储物复制到未使用的存储物块中,然后清除所使用的存储物块中的所有物块,交换两个存储物的作用,完成垃圾回收。

系统中的垃圾对象多的话,复印算法需要复印的生存对象数量不太多。因此,在真正需要垃圾回收的时候,复印算法的效率很高。另外,由于对象在垃圾回收过程中统一复制到新的存储空间,因此可以确保回收后的存储空间没有碎片。这种算法的缺点是系统存折半。

Java新生代串行垃圾回收器使用复制算法的思想。新生代分为eden的空间、from的空间、tom的空间。其中from、空间和to,可视为复印的两个大小相同,地位相同,可以交换角色的空间块。from和to,空间也称为survivor,即幸存者空间,用于保管未回收的对象。

在垃圾回收时,eden空间中的生存对象会被复制到未使用的survivor空间中。(假设是在使用的survivor空间中,假设是在from中的年轻对象也会被复制到otor空间中(大对象或老年对象直接进入老年带,如果tor空间已满,对象也会直接进入老年)。此时,eden、空间和from空间的剩馀对象是垃圾对象,可以直接清空,tou空间保管这次回收后的生存对象。这种改进的复制算法保证了空间的连续性,避免了大量的内存空间浪费。

标记-压缩算法(Mark-Compact)

复制算法的效率是基于生存对象少、垃圾对象多的前提。这种情况在年轻时代经常发生,但在老年时代更常见的情况是大多数对象都是生存对象。

标识-压缩算法是老年人的回收算法,在标识-清除算法的基础上进行了优化。首先,有必要从根节点对所有可达对象进行一次标记,然后不是简单地清理没有标记的对象,而是将所有的生存对象压缩到内存的一端。随后清理界外所有空间。该方法不仅避免了碎片的发生,而且不需要两个相同的存储空间,因此性价比高。

增量算法

在垃圾回收过程中,应用软件处于高消耗的状态。在这样的CPU消耗高的状态下,应用程序的所有线程都会挂断,暂停一切正常的工作,等待垃圾回收的完成。垃圾回收时间过长,应用程序长期悬挂,严重影响用户体验和系统稳定性。

增量算法的基本思想是,如果一次处理所有垃圾,系统需要长时间停止,垃圾收集线程和应用程序线程可以交替执行。每次,垃圾收集线程只收集小区域的内存空间,然后切换到应用程序线程。使用该方式,在垃圾回收过程中,间断地执行应用代码,可以减少系统的停止时间。但是,由于线程切换和上下转换的消耗,垃圾回收的整体成本上升,系统吞吐量下降。

分代(Generational,Collecting)

根据垃圾回收对象的特性,不同阶段最好的方法是使用适当的算法来回收这个阶段的垃圾,分代算法是基于这个想法,内存区间根据对象的特征分成几个,根据每个内存区间的特征以HotSpot虚拟机为例,将所有新对象放入被称为年轻代的存储区域,年轻代的特征是对象很快就会回收,所以在年轻代选择高效的复印算法。当一个物体经过几次回收后仍然存活时,物体将被放入被称为老一代的存储空间。在老一代,几乎所有的对象都经过几次垃圾回收而幸存下来。因此,可以认为这些对象在一段时间内,甚至在应用程序的整个生命周期中,都是常驻内存。如果你仍然使用复制算法来回收旧的一代,你需要复制大量的对象。此外,老一代的回收性价比也低于新一代,这种做法也不理想。

从不同角度分析垃圾采集器,可分为不同类型。

可以通过以下指标评估垃圾处理器的质量。

吞吐量:指在应用程序的生命周期内,应用程序所花费的时间与系统总运行时间的比例。系统总运行时间=应用消耗时间,GC消耗时间。系统运行100min时,GCT耗时1min时,系统吞吐量为(100-1)/100=99%。

垃圾回收器负载:与吞吐量相反,垃圾回收器负载是指记录回收器与系统运行总时间的比例。

停止时间,指垃圾回收器正在运,应用程序的暂停时间。垄断回收器可能停止时间长。使用并发回收器时,由于垃圾回收器和应用交替运行,程序的停止时间变短,但其效率很可能低于垄断垃圾回收器,因此系统的吞吐量可能低。

垃圾回收频率,指垃圾回收器多长时间运行一次。一般来说,垃圾回收器的频率应该越低越好。通常,增加堆积空间可以有效地降低垃圾回收的频率,但回收的停止时间可能会增加。

反应时间,指一个对象被称为垃圾后多长时间内,所占的存储空间被释放。

堆积分配:垃圾回收器对堆积内存的分配方式可能不同。好的垃圾收集器要有合理的堆积内存区间划分。

原文

https://www.ibm.com/developerworks/cn/java/j-lo-JVMGagecollection/