读《JVM虚拟机》- 集中简单的垃圾收集算法

时间:2022-12-27 19:21:33

1.标记-清除算法:

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

a)标记:对不可达对象进行标记(对可回收对象进行标记)

ps:通过可达性分析算法,当一个对象到GCROOT没有任何引用链相连时,则证明此对象不可达(可回收)。

ps:当对象被第一次标记为不可达对象的时候,会进行一次筛选,判断是否要执行finalize方法(重写了finalize方法并尚未执行finalize方法);等到下一次标记时,将会被真正回收。

b)清除:对内存对象直接回收清除

不足有二:

1.效率不足;[标记:采用的是可达性分析,也就是遍历和递归堆中的对象;]

2.标记清除之后会产生大量不连续的内存随便,可能会导致下次分配较大的内存是,没有足够的连续空间而不得不提前出发下一次的垃圾收集动作。

 

2.复制算法

针对新生代的内存对象特点(存活率低)而诞生的垃圾收集算法.

基本思想:

将整个内存分成2块,A和B。(假设为1:1的比例)每一次都只使用其中一块。当其中的一块内存(A)使用完毕了,就将A上的存活的内存对象都复制到B上,

然后对A进行清除处理。每次都只对半个内存区域进行回收,不用考虑内存碎片等复杂的情况。但是内存的使用率就减少了50%.

一般针对新生代,不采取1:1的比例,而是以将内存分为一块较大的 Eden 80%,两块较小的 survivor 10%.也就是说每次的内存使用率可以到达90%。

倘若当未使用survivor空间无法存放另两块中的存活的对象,那么多出来的对象将通过分配担保机制进入老年代。

 

 

3.标记-整理算法

针对老生代的特点(对象存活率较高)而被提出的算法;

a)标记阶段(和标记清除算法中的标记阶段一样)

b)整理阶段(让所有存活的对象向一端移动,然后直接清理掉端边界以外的内存)

 

4.分代收集算法

根据对象存活的周期的不同将内存划分为几块。一般就是把java堆划分成新生代和老生代。根据每个年代的特点采用最适当的收集算法。

新生代使用复制算法,(新生代的存活周期短,每次垃圾收集时,都会发现有大量对象死去。)

老生代使用标记整理算法或者标记清除算法;(老生代的存活周期长,每次垃圾收集时,大量的对象都存活下来了。)

 

超详细超具体的博文 mark下来