Java六种主要的垃圾回收算法和思想

栏目: 编程工具 · 发布时间: 7年前

内容简介:Java语言的一大特点就是可以自动进行垃圾回收处理,无需开发人员过于关注系统资源的释放情况。自动垃圾收集虽然大大减轻了开发人员的工作量,但是也增加了软件系统的负担。一个不合适的垃圾回收方法和策略将会对系统性能造成不良影响。引用计数法是最经典古老的一种垃圾收集方法,它的实现也很简单:对于一个对象A,只要有任何一个对象引用了A,则A的计数器就加1,当引用失效时,引用计数器就减1.只要对象A的引用计数器的值为0,则对象A就不可能再被使用。引用计数法实现简单,只需要为每一个对象配备一个整型计数器即可。但是,它存在一

Java语言的一大特点就是可以自动进行垃圾回收处理,无需开发人员过于关注系统资源的释放情况。自动垃圾收集虽然大大减轻了开发人员的工作量,但是也增加了软件系统的负担。一个不合适的垃圾回收方法和策略将会对系统性能造成不良影响。

1. 引用计数法

引用计数法是最经典古老的一种垃圾收集方法,它的实现也很简单:对于一个对象A,只要有任何一个对象引用了A,则A的计数器就加1,当引用失效时,引用计数器就减1.只要对象A的引用计数器的值为0,则对象A就不可能再被使用。

引用计数法实现简单,只需要为每一个对象配备一个整型计数器即可。但是,它存在一个很严重的问题,即无法处理循环引用的情况,因此在 Java 的垃圾回收器中没有使用这种算法。

一个简单的循环引用示例如下:

对象A和对象B循环引用,此时他们的引用计数器都不为0,但是在系统中已经找不到第三个对象引用了A或者B,也就是说,A和B应该是被回收的垃圾。但是因为循环引用而无法被识别,最终可能会导致内存泄漏。

2. 标记-清除法

标记-清除法是现代垃圾回收算法的基础。

它将垃圾回收分为两个阶段:标记阶段和清除阶段。一种可行的实现是:

  1. 在标记阶段,标记所有从根节点出发的可达对象。因此,所有未被标记的对象就是未被引用的垃圾对象。
  2. 在清除阶段,清除所有未被标记的对象。

而标记-清除法可能产生的最大问题就是空间碎片。回收之后的空间不是连续的,不连续的内存空间的工作效率要低于连续的空间,这是标记-清除法最大的缺点。

3.复制算法

与标记-清除法相比,复制算法是一种相对高效的回收算法。

它的核心思想是:将内存分为两部分,每次只使用其中一部分。在垃圾回收时,将正在使用的内存中的存货对象复制到未使用的内存块中,之后清除正在使用的内存块中的所有对象,交换两个内存的角色,完成垃圾回收。

如果系统中的垃圾对象很多,那么复制算法需要复制的存活对象的数量也不会很多,因此当需要使用复制算法时还是比较高效的。又因为所有对象都会被统一复制到新的内存空间中,所以可以保证回收后的内存空间是没有碎片的。

虽然有以上两大有点,但是复制算法的代价缺点是将系统内存折半。因此单纯的复制算法会让人无法接受。

在Java的新生代串行垃圾回收器中,使用了复制算法。新生代分为eden空间、from空间和to空间三个部分。其中from和to空间可以视为用于复制的两块大小相同、地位相等,且角色可以互换的空间块,它们也被称为survivor空间,即幸存者空间,用于存放未被回收的对象。

在垃圾回收时,eden空间中的存活对象会被复制到未使用的survivor空间中(假设为to),正在使用的survivor空间(假设为from)中的年轻对象也会被复制到to空间中(大对象或者老年对象会直接进入老年代,如果to空间已经满了,则对象也会直接进入老年代)。此时eden和from空间中的剩余对象将都是垃圾对象,可以直接清空,to空间则存放此次回收后存活的对象。

这样改进后的复制算法既保证了空间的连续性,又避免大量内存空间被浪费。

4. 标记-压缩算法

复制算法的高效性是建立在存活对象少,垃圾对象多的前提下。这种情况普遍存在于年轻代,但是在老年代,更常见的情况是大部分对象都是存活对象,如果使用复制算法,由于存活对象多,复制的成本也会很高。

基于老年代垃圾回收的特性,需要使用新的算法,而标记-压缩算法是老年代的一种回收算法,它在标记-清除算法之上做了一些优化。

它和标记-清除算法不同之处在于:在清除阶段,它会将所有的存活对象压缩到内存的另一端。之后清理边界之外的所有空间。这种算法既避免了碎片的产生,又不需要两块相同的内存空间,因此性价比较高。

5. 增量算法

对大部分的垃圾回收算法而言,在垃圾回收的过程中,应用软件的所有线程都会挂起,暂停一切正常工作,等待来回收的完成。如果垃圾回收时间很长,则应用程序会被挂起很久,这会严重影响用户体验和系统稳定性。

增量算法的基本思想就是,让垃圾回收线程和应用线程交替执行,每次只收集一小片区域的内存空间,接着切换应用程序线程。如此往复知道垃圾回收完成。

使用这种方式进行垃圾回收可以减少系统的停顿时间,但是因为线程切换和上下文转换的消耗,会使得垃圾回收的总体成本上升,造成系统吞吐量的下降。

6.分代

前面介绍的几种垃圾回收算法没有哪一种可以完全替代其他算法,它们有各自的优点和缺点。因此,根据垃圾回收对象的特性,使用合适的算法回收,才是明智的选择。

分代就是基于这种思想,它将内存区域根据对象特点分为几块,根据每块内存区间的特点,使用不同的回收算法,提高垃圾回收的效率。

Linux公社的RSS地址https://www.linuxidc.com/rssFeed.aspx

本文永久更新链接地址: https://www.linuxidc.com/Linux/2019-01/156333.htm


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Mashups Web 2.0开发技术—— 基于Amazon.com

Mashups Web 2.0开发技术—— 基于Amazon.com

萨拉汉 / 吴宏泉 / 清华大学 / 2008-1 / 48.00元

《MashupsWeb2.0开发技术(基于Amazon.Com) 》介绍了mashup的底层技术,并且第一次展示了如何创建mashup的应用程序。Amazon.com与Web服务强势结合,拓展了Internet的应用范围,使得开发人员可以把Amazon的数据和其他的可利用资源自由地结合起来创建功能丰富的全新应用程序,这种应用程序叫做mashup。 《MashupsWeb2.0开发技术(基于A......一起来看看 《Mashups Web 2.0开发技术—— 基于Amazon.com》 这本书的介绍吧!

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具