软引用 弱引用(SoftReference WeakReference)

235 阅读2分钟
public class SoftReferenceTest {
    public static void main(String[] args) {
        A a = new A();

        SoftReference<A> softReference = new SoftReference<>(a);


        //第一步
        //我要施加内存压力了,a 占用内存很大 , 把 a =null 释放下内存
        a = null;
        addMemory();


        //第二步
        //诶呀,现在想起来还想再使用a一下,但是a找不到了,后悔莫及
        //于是 SoftReference 诞生了,让SoftReference 把 a 引用起来。
        //当GC 要回收 a 的时候,不好意思 a 被softReference引用了,暂时不能回收,
        //那么对象什么时候被回收呢,当内存快要满的时候,要在 OutOfMemoryError 之前。
        //这样以来可以说明,SoftReference的作用是最大的限度的使用内存,而又不至于让内存溢出。
        //A a = softReference.get(); 的方式取到对象。


        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    try {
                        //第三步
                        //观察对象有没有被释放
                        System.out.println(softReference.get());
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();
    }

    // 添加内存压力
    public static void addMemory() {
        List<B> list = new ArrayList<>();
        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    try {
                        list.add(new B());
                        Thread.sleep(1000);
                        System.out.println("addMemory");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();
    }
}

class A {
    String[] str = new String[500000000];
}

class B {
    String[] str = new String[50000000];
}



public class WeakReferenceTest {

    public static void main(String[] args) {
        A a = new A();

        WeakReference<A> weakReference = new WeakReference<>(a);


        //第一步
        //我要施加内存压力了,a 占用内存很大 , 把 a =null 释放下内存
        a = null;
        addMemory();

        //第二步
        //诶呀,现在想起来还想再使用a一下,但是a找不到了,后悔莫及
        //于是 WeakReference 诞生了,让WeakReference 把 a 引用起来。
        //当GC 要回收 a 的时候,虽然 a 被weakReference引用了, 但是只是个弱引用,GC 大哥你可以回收。
        //这样以来可以说明,WeakReference的作用是可以检测一个对象是否被回收,当然也可以get()对象出来使用。
        //A a = weakReference.get(); 的方式取到对象。


        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    try {
                        //第三步
                        //观察对象有没有被释放
                        System.out.println(weakReference.get());
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();
    }

    // 添加内存压力
    public static void addMemory() {
        List<B> list = new ArrayList<>();
        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    try {
                        list.add(new B());
                        Thread.sleep(1000);
                        System.out.println("addMemory");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();
    }
}

class A {
    String[] str = new String[500000000];
}

class B {
    String[] str = new String[50000000];
}