堆中存放着几乎所有的对象实例,对堆中垃圾对象进行回收的前提就是判断哪些对象已经成为了垃圾对象(不再被任何途经使用的对象)
给每一个对象添加一个引用计数器
注意
:该方法实现简单,效率高,但是因为难以解决对象相互循环引用问题,所以目前主流的虚拟机中并没有选择该算法管理内存。
示例相互循环引用:
package com.example.demo;
/**
* @Description
* @Author heiheihei
* @Date 2021/8/29 16:38
*/
public class Test {
//保存其他对象引用
Object obj=null;
public static void main(String[] args) {
//创建对象
Test objA = new Test();
Test objB = new Test();
//引用其他对象
objA.obj=objB;
objB.obj=objA;
//释放自身对象
objA=null;
objB=null;
//造成A对象依旧引用着B对象,而B对象引用着A对象
//如果使用引用计数法实现的内存管理,将会由于计数器未归零,无法回收对象
}
}
以“GC Roots"对象为起点,向下寻找引用的对象,被找到的对象被标记为非垃圾对象
,而未被标记的对象都为垃圾对象。
GC Roots 根节点:线程栈的本地变量、静态变量、本地方法栈的变量等等.
在java中引用类型分为四种类型:强引用、软引用、弱引用、虚引用。
强引用:最普通的变量引用
public static User user = new User();
软引用:将对象使用SoftReference软引用类型的对象包裹,正常情况不会进行回收
。
未释放出空间存放新的对象,则将会把软引用的对象回收
。软引用可以用来实现内存敏感的高数缓存public static SoftReference<User> user = new SoftReference<User>(new User());
弱引用:将对象使用WeakReference弱引用类型的对象包裹,弱引用与没有引用差不多,GC时会直接进行回收。
public static WeakReference<User> user = new WeakReference<User>(new User());
虚引用:虚引用又称幽灵引用或幻影引用,是最弱的引用关系,几乎不用。
哪怕在可达性分析算法中不可达的对象,也不是
非死不可
,finalize()就是自救的方法。重写finalize()就是如何自救,finalize()是给予对象一次
救命的机会。
流程:
筛选对象是否需要执行finalize()方法(是否覆盖finalize()方法)否则对象直接被回收
诺在finalize()将自己赋值个某个类变量或对象的成员变量(这些不是垃圾对象),那就会在第二次标记时移除
即将回收对象集合
,如果对象这时候还未逃脱,它就真的被回收了.
注意
:一个对象的finalize()方法只会被执行一次,也就是说通过调用finalize方法自救的机会就只有一次。
方法区主要回收的是无用的类,那么如何判断一个类是无用的类的呢?
类的回收必须满足3个条件
事实证明方法区中的类是很难以回收的,所以在实际中方法区GC后没有明显的变化。