gc算法(标记清除,复制,标记整理)

此处记录下对gc算法的理解

1.对于标记清除,分为2部分,先进行标记,然后进行清除,如下图所示:

gc算法(标记清除,复制,标记整理)_第1张图片

对上图中的灰色部分进行垃圾回收,回收后的截图如下所示:

gc算法(标记清除,复制,标记整理)_第2张图片

从图中可知,进行标记清理后,可以看出,清楚后的内存可用内存增加,但是清除垃圾后的内存地址不连接,出现垃圾碎片,当有大对象需要进行内存分配时,会因为找不到足够内存进行分配对象而造成垃圾回收,频繁的垃圾回收影响效率和性能

2.对上一个垃圾收集算法的改进,引出了复制算法

gc算法(标记清除,复制,标记整理)_第3张图片

  所谓复制算法,就是把内存分为2块等同大小的内存空间(A和B),使用A进行内存的使用,当A部分的内存不足以分配对象而引起内存回收时,就会把存活的对象从A内存块放到B内存块中,后把A内存块中的对象全部清除,在B内存块中使用,当B内存不足以分配内存时,就会把B中存活的对象放到A内存块中,然后把B中对象全部清除,如此循环

使用这种方式可以避免出现空间碎片(内存中不连续的空间),不过会浪费一半的内存,降低空间的使用率。

 

3.由于前两种都有问题,提出了第三种垃圾收集算法:标记整理

   前面标记部分同标记清除部分,不同的地方在于,标记清除中只是把可回收的对象进行垃圾回收,不会对剩余的内存空间进行整理,而标记整理则会对存活的对象进行整理,截图对比如下所示:

gc算法(标记清除,复制,标记整理)_第4张图片

标记整理后,截图如下所示:

gc算法(标记清除,复制,标记整理)_第5张图片

从图中也可以看出,整理后的内存,避免了标记清除中的内存碎片的问题,也避免了复制算法中的内存浪费问题,当然,存在的问题就是效率问题了,会比前2者的效率低。

现在的垃圾回收是分代收集算法,针对不同的分代区,选择不同的垃圾收集算法。

这就需要说到虚拟机中的结构:

gc算法(标记清除,复制,标记整理)_第6张图片

其中,堆部分,年轻代是采用复制算法进行垃圾回收,因为年轻代一般都是存活时间不长的对象,在第一次进行垃圾回收的时候,会把大部分的对象清除掉,这种情况下使用复制算法,只需要把少量存活的对象放入到另一块闲置的内存块中即可。

而老年代中,一般对象的存活比例会很高,这种情况下,使用复制算法不能很好的提高性能和效率,把存活的对象移到另一个内存块时,会由于对象存活多而消耗的时间多,从而影响效率,这种情况下,使用标记整理或者标记清除比较合适。

此处为针对垃圾收集算法的笔记整理,后续可能会有补充。

 

你可能感兴趣的:(Java基础学习笔记)