Java 垃圾回收算法

(1).标记-清除算法:

最基础的垃圾收集算法,算法分为“标记”和“清除”两个阶段:

首先标记出所有需要回收的对象,在标记完成之后统一回收掉所有被标记的对象。

标记-清除算法的缺点有两个

1.效率问题,标记和清除效率都不高。

2.标记清除之后会产生大量的不连续的内存碎片,会导致当程序需要为较大对象分配内存时无法找到足够的连续内存而不得不提前触发另一次垃圾收集动作

(2).复制算法:

将可用内存按容量分成大小相等的两块,每次只使用其中一块,当这块内存使用完了,就将还存活的对象复制到另一块内存上去,然后把使用过的内存空间一次清理掉。这样使得每次都是对其中一块内存进行回收,内存分配时不用考虑内存碎片等复杂情况,只需要移动堆顶指针,按顺序分配内存即可,实现简单,运行高效。

复制算法的缺点显而易见,可使用的内存降为原来一半。

(3).标记-整理算法:

标记-整理算法在标记-清除算法基础上做了改进,标记出所有需要回收的对象,在标记完成之后不是直接对可回收对象进行清理,而是让所有存活对象都向一端移动,在移动过程中清理掉可回收的对象,这个过程叫做整理。

相比与标记-清除算法的优点是内存被整理以后不会产生大量不连续内存碎片问题。

复制算法对象存活率高的情况下要执行较多的复制操作,效率将会变低。

在这种情况下使用标记-整理算法效率会大大提高。

(4).分代收集算法:

根据内存中对象的存活周期不同,将内存划分为几块,java的虚拟机中一般把内存划分为新生代和年老代,

当创建对象时一般在新生代中分配内存空间,当新生代垃圾收集器回收几次之后仍然存活的对象会被移动到年老代内存中,

当大对象在新生代中无法找到足够的连续内存时也直接在年老代中创建。

Java虚拟机联合使用了:分代复制、标记-清除和标记-整理算法。

java虚拟机垃圾收集器关注的内存结构如下:

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

新生代采用复制算法,因为新生代中每次垃圾回收都要回收大部分对象,需要复制的操作次数较少,但是实际中并不是按照1:1的比例来划分新生代空间的,

一般来说是将新生代划分为一块较大的Eden空间两块较小的Survivor空间。

每次使用Eden空间和其中的一块Survivor空间,当进行回收时,将Eden和Survivor中还存活的对象复制到另一块Survivor空间中,然后清理掉Eden和刚才使用过的Survivor空间。

猜你喜欢

转载自blog.csdn.net/qq_39731011/article/details/118852475