java 引用

强引用

Object obj = new Student();
上面这块代码就是强引用,当你不在使用的时候才会进行GC。什么是再也不使用了,有如下二状况:
1 obj = null
2 当前方法执行完毕java

软引用

public static void main(String[] args) {
        SoftReference<Stu> s1 = soft();
        System.out.println(String.format("当前对象是否被回收:%s",s1.get() == null));

        SoftReference<Stu> s2 = soft();
        System.out.println(String.format("当前对象是否被回收:%s",s1.get() == null));

        SoftReference<Stu> s3 = soft();
        System.out.println(String.format("当前对象是否被回收:%s",s1.get() == null));

        SoftReference<Stu> s4 = soft();
        System.out.println(String.format("当前对象是否被回收:%s",s1.get() == null));

        SoftReference<Stu> s5 = soft();
        System.out.println(String.format("当前对象是否被回收:%s",s1.get() == null));
    }

    public static SoftReference<Stu> soft(){
        Stu s1 = new Stu();
        s1.a1 = new int[1024*1024];
        SoftReference<Stu> soft1 = new SoftReference<>(s1);
        System.out.println("total:"+Runtime.getRuntime().totalMemory()/1024/1024);
        System.out.println("max:"+Runtime.getRuntime().maxMemory()/1024/1024);
        System.out.println("free:"+Runtime.getRuntime().freeMemory()/1024/1024);
        return soft1;

    }

运行上面的程序,设置-Xms20m -Xmx20m,因为int占4个字节,所以执行到S5的时候,若是是强引用的话,就会抛内存溢出的异常。可是若是是软引的话,会在分配S5的时候,对S1进行回收,程序运行结果以下:code

total:19
max:19
free:14
当前对象是否被回收:false
total:19
max:19
free:10
当前对象是否被回收:false
total:19
max:19
free:6
当前对象是否被回收:false
total:19
max:19
free:2
当前对象是否被回收:false
total:19
max:19
free:14
当前对象是否被回收:true

弱引用

public static void main(String[] args) {
        WeakReference<Stu> s1 = weak();
        System.out.println(String.format("当前对象是否被回收:%s",s1.get() == null));

        WeakReference<Stu> s2 = weak();
        System.out.println(String.format("当前对象是否被回收:%s",s1.get() == null));

        WeakReference<Stu> s3 = weak();
        System.out.println(String.format("当前对象是否被回收:%s",s1.get() == null));

        WeakReference<Stu> s4 = weak();
        System.out.println(String.format("当前对象是否被回收:%s",s1.get() == null));

        WeakReference<Stu> s5 = weak();
        System.out.println(String.format("当前对象是否被回收:%s",s1.get() == null));
    }

    public static WeakReference<Stu> weak(){
        Stu s1 = new Stu();
        s1.a1 = new int[1024*1024];
        WeakReference<Stu> weak = new WeakReference<>(s1);
        System.out.println("total:"+Runtime.getRuntime().totalMemory()/1024/1024);
        System.out.println("max:"+Runtime.getRuntime().maxMemory()/1024/1024);
        System.out.println("free:"+Runtime.getRuntime().freeMemory()/1024/1024);
        return weak;

    }

直接看执行结果:orm

total:19
max:19
free:14
当前对象是否被回收:false
total:19
max:19
free:14
当前对象是否被回收:true
total:19
max:19
free:14
当前对象是否被回收:true
total:19
max:19
free:14
当前对象是否被回收:true
total:19
max:19
free:14
当前对象是否被回收:true

虚引用

虚引用主要用来清理对象用的,相似于对象的finalize方法。对象

public static void main(String[] args) throws InterruptedException {
        ReferenceQueue<Stu> queue = new ReferenceQueue<>();
        Map<PhantomReference<Stu>,PhantomReference<Stu>> map = new HashMap<>();
        PhantomReference<Stu> s1 = phantom(queue);
        map.put(s1,s1);
        recycle(queue,map);
        System.out.println(String.format("当前对象是否被回收:%s",map));

        s1 = phantom(queue);
        map.put(s1,s1);
        recycle(queue,map);

        System.out.println(String.format("当前对象是否被回收:%s",map));

        s1 = phantom(queue);
        map.put(s1,s1);
        recycle(queue,map);

        System.out.println(String.format("当前对象是否被回收:%s",map));

        s1 = phantom(queue);
        map.put(s1,s1);
        recycle(queue,map);

        System.out.println(String.format("当前对象是否被回收:%s",map));
        s1 = phantom(queue);
        map.put(s1,s1);
        recycle(queue,map);


        System.out.println(String.format("当前对象是否被回收:%s",map));
    }

    public static void recycle( ReferenceQueue<Stu> queue,Map<PhantomReference<Stu>,PhantomReference<Stu>> map){
        PhantomReference<Stu> phantom = null;
        while((phantom = (PhantomReference<Stu>)queue.poll()) != null){
            System.out.println(phantom);
            map.remove(phantom);
        }
    }

    public static PhantomReference<Stu> phantom(ReferenceQueue<Stu> que){
        Stu s1 = new Stu();
        s1.a1 = new int[1024*1024];
        PhantomReference<Stu> phantom = new PhantomReference<>(s1,que);
        System.out.println("total:"+Runtime.getRuntime().totalMemory()/1024/1024);
        System.out.println("max:"+Runtime.getRuntime().maxMemory()/1024/1024);
        System.out.println("free:"+Runtime.getRuntime().freeMemory()/1024/1024);
        return phantom;

    }

虚引用与软引用和弱引用不一样,第一次回收的时候,只是将对象加入到引用队列,并无真正清楚对象,虚引用须要将引用置空,才会回收整个对象,这也是与软引用与弱引用不一致的地方,如下执行结果:队列

total:19
max:19
free:14
当前对象是否被回收:{java.lang.ref.PhantomReference@a881b5=java.lang.ref.PhantomReference@a881b5}
total:19
max:19
free:10
java.lang.ref.PhantomReference@a881b5
当前对象是否被回收:{java.lang.ref.PhantomReference@84aee7=java.lang.ref.PhantomReference@84aee7}
total:19
max:19
free:6
java.lang.ref.PhantomReference@84aee7
当前对象是否被回收:{java.lang.ref.PhantomReference@9ee92=java.lang.ref.PhantomReference@9ee92}
total:19
max:19
free:2
当前对象是否被回收:{java.lang.ref.PhantomReference@f39991=java.lang.ref.PhantomReference@f39991, java.lang.ref.PhantomReference@9ee92=java.lang.ref.PhantomReference@9ee92}
total:19
max:19
free:6
当前对象是否被回收:{java.lang.ref.PhantomReference@f39991=java.lang.ref.PhantomReference@f39991, java.lang.ref.PhantomReference@12b3a41=java.lang.ref.PhantomReference@12b3a41, java.lang.ref.PhantomReference@9ee92=java.lang.ref.PhantomReference@9ee92}

若是map不执行remove方法的话,会报内存溢出。内存

注意事项

软引用,弱引用与虚引用中的对象,若是有强引用是不可以被回收的。rem

相关文章
相关标签/搜索