在java中是通过引用来和对象进行关联的,也就是说如果要操作对象,必须通过引用来进行。
那么很显然一个简单的办法就是通过引用计数来判断一个对象是否可以被回收。
不失一般性,如果一个对象没有任何引用与之关联,则说明该对象基本不太可能在其他地方被使用到,那么这个对象就成为可被回收的对象了。
这种方式成为引用计数法。特点是实现简单,而且效率较高,但是它无法解决循环引用的问题,因此在Java中并没有采用这种方式(Python采用的是引用计数法)。
为了解决这个问题,在Java中采取了 可达性分析法。
该方法的基本思想是通过一系列的“GC Roots”对象作为起点进行搜索,如果在“GC Roots”和一个对象之间没有可达路径,则称该对象是不可达的,不过要注意的是被判定为不可达的对象不一定就会成为可回收对象。被判定为不可达的对象要成为可回收对象必须至少经历两次标记过程,如果在这两次标记过程中仍然没有逃脱成为可回收对象的可能性,则基本上就真的成为可回收对象了。
线程创建时有栈空间,和堆空间。参考:java栈和堆
栈中存放对象的引用,堆中存放对象的内容。
GC Roots也即检查栈中的引用 与堆中存放的对象,看哪个对象没有被引用,标记为可回收。
比较常见的将对象判定为可回收对象的情况:
1)显示地将某个引用赋值为null或者将已经指向某个对象的引用指向新的对象。
2)局部引用所指向的对象。
3)只有弱引用(WeakReference)与其关联的对象。
内存不足的情况下, 会将SoftReference对象判定为可回收对象