victory的博客

长安一片月,万户捣衣声

0%

Java | java引用

强软弱虚四大引用

import java.lang.ref.PhantomReference;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

class StudentClass{
    @Override
    protected void finalize() throws Throwable{
        System.out.println("student对象被回收了");
    }
}

public class ReferencesTest {
    public static void main(String[] args) {
        
        /**
         * 强引用
         * 只要某个对象有强引用与之关联,这个对象永远不会被回收,即使内存不足,JVM宁愿抛出OOM,也不会去回收。
         */
        //StudentClass student = new StudentClass();
        //student = null;//断开强引用与对象之间的关联
        //System.gc();
        
        
        /**
         * 软引用
         * 内存不足时,JVM会回收软引用关联的对象
         * 
         * 比较适合用作缓存,当内存足够,可以正常的拿到缓存,当内存不够,就会先干掉缓存,不至于马上抛出OOM。
         */
//        SoftReference<byte[]> softReference = new SoftReference<byte[]>(new byte[1024*1024*10]);
//        System.out.println(softReference.get());
//        System.gc();
//        System.out.println(softReference.get());
//        byte[] bytes = new byte[1024 * 1024 * 10];
//        System.out.println(softReference.get());
        
        /**
         * 弱引用
         * 不管内存是否足够,只要发生GC,都会被回收
         */
//        WeakReference<byte[]> weakReference = new WeakReference<byte[]>(new byte[1]);
//        System.out.println(weakReference.get());
//        System.gc();
//        System.out.println(weakReference.get());
        
//        [B@15db9742
//         null
        
        /**
         * 虚引用
         * 特点一:无法通过虚引用来获取对一个对象的真实引用
         * 特点二:虚引用必须与ReferenceQueue一起使用,当GC准备回收一个对象,如果发现它还有虚引用,就会在回收之前,把这个虚引用加入到与之关联的ReferenceQueue中。
         * 
         * 
         * Unlike soft and weak references, phantom references are not
 automatically cleared by the garbage collector as they are enqueued.  An
object that is reachable via phantom references will remain so until all
such references are cleared or themselves become unreachable.
         */
        ReferenceQueue<Object> referenceQueue = new ReferenceQueue<>();
        List<byte[]> bytes = new ArrayList<>();
        PhantomReference<StudentClass> reference = new PhantomReference<StudentClass>(new StudentClass(),referenceQueue);
        
        new Thread(() -> {
            for (int i = 0; i < 100;i++ ) {
                bytes.add(new byte[1024 * 1024]);
            }
        }).start();
 
        new Thread(() -> {
            while (true) {
                Reference poll = referenceQueue.poll();
                if (poll != null) {
                    System.out.println("虚引用被回收了:" + poll);
                }
            }
        }).start();
        Scanner scanner = new Scanner(System.in);
        scanner.hasNext();
    }
}