JVM常见的垃圾收集算法
https://www.jianshu.com/p/99772ad092d3
标记-清除算法:
标记-清除算法采用从根集合进行扫描,对存活的对象进行标记,标记完毕后,再扫描整个空间中未被标记的对象,进行回收。标记-清除算法不需要进行对象的移动,并且仅对不存活的对象进行处理,在存活对象比较多的情况下极为高效,但由于标记-清除算法直接回收不存活的对象,因此会造成内存碎片。
复制算法:
这种收集算法将堆栈分为两个域,常称为半空间。每次仅使用一半的空间,JVM生成的新对象则放在另一半空间中。GC运行时,它把可到达对象复制到另一半空间,从而压缩了堆栈。这种方法适用于短生存期的对象,持续复制长生存期的对象则导致效率降低。并且对于指定大小堆来说,需要两倍大小的内存,因为任何时候都只使用其中的一半。
标记整理算法:
标记-整理算法采用标记-清除算法一样的方式进行对象的标记,但在清除时不同,在回收不存活的对象占用的空间后,会将所有的存活对象往一端空闲空间移动,并更新对应的指针。标记-整理算法是在标记-清除算法的基础上,又进行了对象的移动,因此成本更高,但是却解决了内存碎片的问题。
分代收集算法:
在上边三种收集思想中加入了分代的思想。
finalize方法什么作用?
对于一个对象来说,在被判断没有 GCroots 与其相关联时,被第一次标记,然在第二次标记判断该对象是否应该执行finalize方法(判断依据:如果对象的finalize方法被复写,并且没有执行过,则可以被执行),在finalize()方法中没有重新与引用链建立关联关系的,将被进行第二次标记,逃离本次回收,继续存活。如果允许执行那么这个对象将会被放到一个叫F-Query的队列中,等待被执行。(注意:由于finalize的优先级比较低,所以该对象的的finalize方法不一定被执行,即使被执行了,也finalize方法不保证一定会执行完)