1、引用计数法(Reference count):
原理是:给对象添加一个引用计数器,每当有一个地方引用该对象时,计数器加1,当引用失效时,计数器减1,当计数器值为0时表示该对象不再被使用。
优点:实现简单,效率较高。
缺点:很难解决对象之间相互循环引用的问题,主流Java虚拟机没有选用引用计数法来管理内存。
如父对象有一个对子对象的引用,子对象反过来引用父对象。这样,他们的引用计数永远不可能为0。
public class abc_test {
public static void main(String[] args) {
MyObject object1=new MyObject();
MyObject object2=new MyObject();
object1.object=object2;
object2.object=object1;
object1=null;
object2=null;
}
}
class MyObject{
MyObject object;
}
这段代码是用来验证引用计数算法不能检测出循环引用:
最后面两句将object1和object2赋值为null,也就是说object1和object2指向的对象已经不可能再被访问,
但是由于它们互相引用对方,导致它们的引用计数器都不为0,那么垃圾收集器就永远不会回收它们。
2、可达性分析算法(Root Searching):
可达性分析算法是从离散数学中的图论引入的,程序把所有的引用关系看作一张图,从一个节点GC ROOT开始,寻找对应的引用节点,找到这个节点以后,
继续寻找这个节点的引用节点,当所有的引用节点寻找完毕后,剩余的节点则被认为是没有被引用到的节点,即无用的节点,无用的节点将会被判定为是可回收的对象。
在Java语言中,可作为GC Roots的对象包括下面几种:
a) 虚拟机栈中引用的对象(栈帧中的本地变量表);
b) 方法区中类静态属性引用的对象;
c) 方法区中常量引用的对象;
d) 本地方法栈中JNI(Native方法)引用的对象。
可达性分析算法会不会出现对象间循环引用问题呢?
那就是不会出现对象间循环引用问题,因为 GC Root 在对象图之外,是特别定义的 "起点",不可能被对象图内的对象所引用。
根对象:肯定不能被回收的对象
被根对象间接或直接引用的对象,就不能被回收;反之这个对象可以作为垃圾,将来被回收。
重点:
Java 虚拟机中的垃圾回收器采用可达性分析来探索所有存活的对象,扫描堆中的对象,看是否能够沿着 GC Root对象 为起点的引用链找到该对象,找不到,表示可以回收
哪些对象可以作为 GC Root ?
五种引用:强引用、软引用、弱引用、虚引用、终结引用
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。