❒ 引用计数法
✔ 一个对象被引用了一次,在当前的对象头上递增一次引用次数,如果这个对象的引用次数为0,代表这个对象可回收
✔ 当对象间出现了循环引用的话,则引用计数法就会失效(循环引用,会引发内存泄露)
step 1、实例A 引用计数加 1,引用计数 = 1;
step 2、实例B 引用计数加 1,引用计数 = 1;
step 3、实例B 引用计数加 1,引用计数 = 2;
step 4、实例A引用计数加 1,引用计数 = 2;
step 5、objA 引用不再指向实例 A,实例 A 的引用计数减为 1;
step 6、objB 引用计数不再指向实例 B,实例B的引用计数减为 1。
到此,GCObject 的实例 A 和 实例 B 的引用计数都不为 0, 此时如果执行垃圾回收,实例 A 和实例 B 是不会被回收的,也就出现内存泄漏了。
❒ 可达性分析算法
✔ 现在的虚拟机采用的都是通过可达性分析算法来确定哪些内容是垃圾。
✔ 扫描堆中的对象,看是否能够沿着GC Root对象为起点的引用链找到该对象,找不到,表示可以回收。
❒ 哪些对象可以作为 GC Root?
✔ 虚拟机栈(栈帧中的局部变量表)中引用的对象
✔ 方法区中类静态属性(被static修饰符修饰的类属性)引用的对象
✔ 方法区中常量(被final修饰符修饰的类属性)引用的对象
✔ 本地方法栈中JNI(即一般说的Native方法)引用的对象