从finalize的执行来看强引用、弱引用、软引用

finalize的执行来看什么是GC Root我们测试了不同GC Root可达时,对对象finalize方法的执行的影响。下面我们测试一下不同引用对对象finalize方法的执行的影响。

public class RootTest {
    static int gcTime = 0;

    public static void main(String[] args) throws InterruptedException {

        SoftReference softReference = new SoftReference<>(new UnusedLock("soft reference"));
        WeakReference weakReference = new WeakReference<>(new UnusedLock("weak reference"));
        new UnusedLock("no reference");
        UnusedLock unusedLock = new UnusedLock("strong reference");

        new Thread() {
            @Override
            public void run() {
                int x = 0;
                synchronized (new UsedLock()) {
                    while (x < 3) {
                        System.out.println("Thread run " + ++x);
                        try {
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    System.out.println("Thread run over");
                }
            }

            @Override
            protected void finalize() throws Throwable {
                super.finalize();
                System.out.println("Thread finalize() " + Thread.currentThread().getName());
            }
        }.start();

        gc();
        Thread.sleep(5000);
        gc();
        Thread.sleep(5000);
    }

    static void gc() {
        System.out.println("gc start " + ++gcTime);
        System.gc();
        System.out.println("gc over " + gcTime);
    }
}


class UsedLock {
    @Override
    protected void finalize() throws Throwable {
        super.finalize();
        System.out.println("UsedLock finalize()");
    }
}

class UnusedLock {
    private String sign = null;

    public UnusedLock(String sign) {
        this.sign = sign;
    }

    @Override
    protected void finalize() throws Throwable {
        super.finalize();
        System.out.println("UnusedLock finalize(): " + sign);
    }
}

我们分别使用软引用、弱引用、强引用以及不引用来测试对象finalize方法的执行

运行结果:

Thread run 1
gc start 1
UnusedLock finalize(): no reference
UnusedLock finalize(): weak reference
gc over 1
Thread run 2
Thread run 3
Thread run over
gc start 2
gc over 2
UsedLock finalize()
Thread finalize() Finalizer

可见,第一次执行gc时,没有被引用的对象和弱引用的对象finalze方法被调用,软引用和强引用的对象finalze方法没有被调用。

第二次执行gc时,软引用和强引用的对象finalze方法也没有被调用。

我们来模拟一下内存不足时的情况,代码如下:

public class RootTest {
    static int gcTime = 0;

    public static void main(String[] args) throws InterruptedException {

        SoftReference softReference = new SoftReference<>(new UnusedLock("soft reference"));
        WeakReference weakReference = new WeakReference<>(new UnusedLock("weak reference"));
        new UnusedLock("no reference");
        UnusedLock unusedLock = new UnusedLock("strong reference");
        byte[] bytes = new byte[1024 * 1024 * 1024];
        System.out.println(bytes.length);
        bytes = new byte[1024 * 1024 * 1024];
        System.out.println(bytes.length);

        new Thread() {
            @Override
            public void run() {
                int x = 0;
                synchronized (new UsedLock()) {
                    while (x < 3) {
                        System.out.println("Thread run " + ++x);
                        try {
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    System.out.println("Thread run over");
                }
            }

            @Override
            protected void finalize() throws Throwable {
                super.finalize();
                System.out.println("Thread finalize() " + Thread.currentThread().getName());
            }
        }.start();

//        gc();
//        Thread.sleep(5000);
//        gc();
//        Thread.sleep(5000);
    }

    static void gc() {
        System.out.println("gc start " + ++gcTime);
        System.gc();
        System.out.println("gc over " + gcTime);
    }
}


class UsedLock {
    @Override
    protected void finalize() throws Throwable {
        super.finalize();
        System.out.println("UsedLock finalize()");
    }
}

class UnusedLock {
    private String sign = null;

    public UnusedLock(String sign) {
        this.sign = sign;
    }

    @Override
    protected void finalize() throws Throwable {
        super.finalize();
        System.out.println("UnusedLock finalize(): " + sign);
    }
}

我们不再主动调用gc了,直接分两次申请1024 * 1024 * 1024 byte的内存,看下运行结果:

1073741824
UnusedLock finalize(): soft reference
UnusedLock finalize(): no reference
UnusedLock finalize(): weak reference
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
	at at.miao.java_lib.RootTest.main(RootTest.java:17)

可见,第一次申请成功了,但是第二次申请的时候内存不足了,这时候软引用、无引用、弱引用的对象finalize方法都被调用了,对象被回收后剩余内存还是不足,造成了OutOfMemoryError。

软引用会在内存不足时被GC回收。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值