浅谈gc-垃圾回收

xiaoxiao2021-02-27  323

垃圾回收(Garbage Collection 简称GC

垃圾回收几种常用的算法有

l 引用计数法

l 标记清除法

l 复制算法

l 标记压缩法

引用计数法

引用计数法实现非常简单,对于对象A,只要有任何对象引用了A,则A的引用计数器则加1,当引用失效时则减1。只要对象A的引用计数器达到0,则对象A是不能被使用的,在下次GC时,则被当做回收对象被回收。

 

引用计数算法只需要为每个对象增加一个引用计数器即可。但是引发两个比较严重的问题:

1. 无法处理循环引用的对象,相互引用。所以Java中排除掉此种回收算法。

2. 每次引用产生跟消除时,都需要做一次加减法操作,对效率会有一定的影响。

 

 

标记清除法

首先介绍一下,标记清除法是现在垃圾回收算法的基础。标记清除法讲垃圾回收分为两个阶段:标记计算、清除阶段。一种可行的实现是通过对象根节点,标记所有从跟节点开始的所有可达对象。因此,未被标记的对象就是未被引用对象。然后在清除阶段中清除所有未被标记的对象。但是此算法有个非常大的弊端,会产生很多内存空间碎片。空间碎片使用的效率相对来说是比较低下的。

 

 

复制算法

复制算法的核心思想是:将原有的内存一分为二,每次仅仅只是使用其中的一块内存。其中复制算法回收内存分几步:第一步把所有的正在使用的对象复制到未被使用的内存中。第二步把正在使用的内存全部清空。第三步交换内存角色,完成垃圾回收。

此算法的缺点是,复制算法首先要折损一半内存,还有就是当存活对象远远多于回收对象时,此算法效率相比之下就非常低了。但是此算法优势是回收内存以后,不会存在内存碎片。

 

Java的新生代串行垃圾回收器中,使用了复制算法的思想。新生代中首先会有大量经常被回收的内存,新生代又分为Eden区,from区,to区。其中from区、to区被称为survivor区(幸存者空间),用于存放未被回收对象。另外介绍一下from区跟to区两块内存空间大小相等,地位相等,可进行角色互换的空间块。

 

上图所示复制算法是适用于新生代回收机制的,效果比较好。(新生代是回收对象多于存活对象)

 

标记压缩法

上述复制算法的有个弊端是损耗一倍内存作为替补区,标记压缩算法把此算法进行优化了一下。标记压缩算法在老年代回收使用比较多,跟标记算法一样,也是从对象的跟节点进行标记,但是之后并不是简单的清除对象。而是把可存活对象移动到内存一端,并且保存引用关系。最后清理掉所有边界外边的对象。这样类似在标记算法做完以后重新做一次内存整理。

 

 

 

 

 

 

 

 

 

转载请注明原文地址: https://www.6miu.com/read-4006.html

最新回复(0)