垃圾收集器 (Garbage Collection, GC) 的诞生引导出了三个问题:
哪些内存需要回收?
什么时候回收?
如何回收?
对于线程独占的三个区域 (程序计数器虚拟机栈本地方法栈) 不用过多的考虑垃圾回收的问题, 因为他们随着线程创建而生, 随着线程结束而消失然而 Java 堆和方法区则不一样, 一个接口的多个实现类需要的内存可能不一样, 一个方法中的多个分支需要的内存也不一样, 我们只有在程序运行的的时候才知道会创建哪些对象, 这部分的内存分配是动态的, 所以这也是 GC 所关注的方面
如何判断对象已死
(1)引用计数法: 给对象添加一个引用计数器, 每当一个地方引用它, 就加一, 引用失效, 就减 1 引用计数法实现比较简单, 判定效率也高, 但是往往有这样一种情况, 两个对象相互引用, 除此之外别无它用, 这样算不算垃圾对象? 在经过验证之后发现, 这样的对象也会被 GC 回收, 因此我们可以判定, Java 虚拟机的 GC 采用的并不是这种机制
(2)可达性分析法: 这个算法的基本思想就是通过一系列的称为 GC Roots 的对象作为起始点, 从这些结点开始向下搜索, 搜索走过的路径称为引用链当一个对象没有任何引用链相连时, 我们可以得到这个对象是不可用的, 于是这个对象会被判定是可回收的对象
生存还是死亡
即时在可达性分析法中不可达的对象, 也并非是非死不可的对象, 这时候他们暂时处于一个缓刑状态, 要想真正的宣告一个对象的死亡, 至少经历两个标记过程: 如果对象不可达, 那么它将会被第一次标记并且进行一次筛选, 筛选的条件是此对象是否有必要执行 finalize()方法, 如果 (1) 没有这种方法 (2) 已经执行过这种方法, 那么就可以看做没有必要执行如果对象被判定有必要执行 finalize 方法, 那么这个对象将会被放在一个叫 F-Queue 的队列之中, 并在稍后由一个虚拟机自动建立低优先级的 Finalize 线程去执行它如果对象在这次处理中拯救了自己, 和其他建立了联系, 那么就会被移除即将回收集合如果还是没有任何联系, 那就会被真正回收掉
来源: http://www.bubuko.com/infodetail-2493606.html