判断对象存活方法及回收方法

引用计数方法

给对象添加一个引用计数器,当有对象引用它时,计数器的值就+1,引用实效时,计数器的值-1。
但是这个方法却解决不了相互引用循环的问题。
比如

class Haha {
    public Object instant = null;
    public static void test(){
        Haha A = new Haha();
        Haha B = new Haha();
        A.instant = B;
        B.instant = A;
        A = null;
        B = null;
        System.gc();
    }
}

如果虚拟机采用这种方法,那么这两个对象将不会被回收,但是通过运行,可以发现,GC对这两个对象进行了回收,可以得到一个结论,虚拟机并非采用对象引用的方法。

可达性分析算法

这个算法的基本思想是通过一系列的 “GC Root“ 作为起点,GC Root向下路过的路径是引用链,如果一个对象到GC Root没有引用链,说明这个对象是不可达的,那么虚拟机就判断是可回收对象。

能称为GC Root有下面几种:
1.虚拟机栈中引用的对象。
2.方法区中的静态对象。
3.方法区中的常量对象。
4.native中引用的对象。

但是,GC并不是只能回收那些不可达对象,如果一些对象 “食之无味,弃之可惜”,或者内存不够用,那么GC也会进行回收,取决于引用的类型:

1.强引用

就是我们new出来的对象,存在于堆中,这是垃圾收集器永远不会回收的对象。
大家不要以为new出来的对象永远不能被回收!
在一个函数中,A a = new A(),new出来的对象放在堆中,而a是
强引用,放在栈中,函数结束,a弹出栈, 生命周期结束,堆中new出来的对象也会被回收。
所以说,强引用如果出现在方法中,不用担心 不把它设置 = null 会出现内存泄漏,因为执行方法时,强引用放在栈中,生命周期结束就自然回收了

2.软引用

将要内存泄漏时,会把软引用指向的对象列到回收范围进行第二次回收。如果还是内存泄漏,那就抛出内存溢出异常。

3.弱引用

可以理解成,无论内存情况如何,下次gc的时候,就是你的回收之日。

4.虚引用

这个引用对它指向的对象不会产生任何影响,只是当这个对象被回收时,发出系统通知。

回收方法区

上面的算法回收的对象都是堆,而方法区也需要回收,但是回收方法区的效率很低,因为方法区太小了~~
方法区相当于堆的逻辑部分,堆存放的时对象实例,而方法区存放的时它的类信息,常量,所以gc回收的是无用的类和无用的常量。
回收方法:
1.无用常量:没对象引用它就回收。
2.无用类:堆不存在它的实例,加载它的ClassLoader回收了,它的Class对象没有被引用,满足以上三个条件,它就是无用类,可以被回收了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值