Java垃圾回收机制

      Java有垃圾回收器负责回收无用对象占据的内存空间。但也有特殊情况:假定你的对象(并非使用new)获得了一块“特殊”的内存区域,由于垃圾回收器只知道释放那些经由new分配的内存,所以它不知道该如何释放该对象的这块“特殊”内存。

      Java允许在类中定义一个名为finalize()方法。一旦垃圾回收期准备好释放对象占用的内存空间,首先调用其finalize()方法,并且在下一次垃圾回收动作发生时,才会真正回收对象占用的内存。

     在Java中,对象并非总是被垃圾回收,只要程序没有濒临内存空间用完的那一刻,对象占用的空间就中也得不到释放。如果程序执行结束,并且垃圾回收器一直没有释放创建的对象,程序结束退出后资源也会全部返回给操作系统。

        这个垃圾回收策略避免了频繁垃圾回收造成的开销,Java虚拟机并未面临内存耗尽的情形,它是不会浪费时间去。

finalize()在什么时候被调用?
* 所有对象被Garbage Collection时自动调用,比如运行System.gc()的时候
* 显式的调用finalize方法

package finalize;

/**
 * 程序没有濒临内存空间用完,对象占用的空间就中也得不到释放,不会调用finalize()方法,
 * 程序执行结束,并且垃圾回收器一直没有释放创建的对象,程序结束退出后资源也会全部返回给操作系统。
 */
public class FinalizeTest {
    public static void main(String[] args) {
        for(int i = 0; i < 10; i++) {
            Test t = new Test(i);
        }
    }

}

class Test {

    public Test(int i) {
        System.out.println("创建:" + this + "->" + i);
    }

    @Override
    protected void finalize() throws Throwable {
        super.finalize();
        System.out.println("资源回收:" + this);
    }
}

     程序运行情况如下,程序内存空间充足,垃圾回收器一直没有释放创建的对象,程序结束退出后资源也会全部返回给操作系统。

	创建:finalize.Test@1d44bcfa->0
        创建:finalize.Test@266474c2->1
        创建:finalize.Test@6f94fa3e->2
        创建:finalize.Test@5e481248->3
        创建:finalize.Test@66d3c617->4
        创建:finalize.Test@63947c6b->5
        创建:finalize.Test@2b193f2d->6
        创建:finalize.Test@355da254->7
        创建:finalize.Test@4dc63996->8
        创建:finalize.Test@d716361->9

        进程完成,退出码 0

         运行System.gc(),所有对象被Garbage Collection时自动调用,程序如下:    

package finalize;

/**
 * 运行System.gc(),所有对象被Garbage Collection时自动调用
**/
public class FinalizeTest {
    public static void main(String[] args) {
        for(int i = 0; i < 10; i++) {
            Test t = new Test(i);
        }
        System.out.println("gc()-start...");
        System.gc();
        System.out.println("gc()-end...");
    }

}

class Test {

    public Test(int i) {
        System.out.println("创建:" + this + "->" + i);
    }
    @Override
    protected void finalize() throws Throwable {
        super.finalize();
        System.out.println("资源回收:" + this);
    }
}

          程序执行情况如下所示:

        创建:finalize.Test@1d44bcfa->0
        创建:finalize.Test@266474c2->1
        创建:finalize.Test@6f94fa3e->2
        创建:finalize.Test@5e481248->3
        创建:finalize.Test@66d3c617->4
        创建:finalize.Test@63947c6b->5
        创建:finalize.Test@2b193f2d->6
        创建:finalize.Test@355da254->7
        创建:finalize.Test@4dc63996->8
        创建:finalize.Test@d716361->9
        gc()-start...
        gc()-end...
        资源回收:finalize.Test@d716361
       资源回收:finalize.Test@4dc63996
        资源回收:finalize.Test@355da254
        资源回收:finalize.Test@2b193f2d
        资源回收:finalize.Test@63947c6b
        资源回收:finalize.Test@66d3c617
        资源回收:finalize.Test@5e481248
        资源回收:finalize.Test@6f94fa3e
        资源回收:finalize.Test@266474c2
        资源回收:finalize.Test@1d44bcfa

        进程完成,退出码 0

        Java9中finalize方法已经被废弃,占有非堆资源的对象实例,类应该提供一个方法以明确释放这些资源,如果合适的话他们也应该实现AutoCloseable接口, java.lang.ref.Cleaner和java.lang.ref.PhantomReference提供更灵活和有效的方式,在对象无法再访问时释放资源。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值