• 强软弱虚引用


    强软弱虚,是 Java 中比较主流的四种引用。(多念念,就顺口了)

    从这四种引用的作用来看(接下来你会看到),引用,与对象的存活密不可分。也许正是因为有了 JVM 的垃圾收集器,才有了这四种引用。

    我觉得直接看四种引用的概念比较好:

    • 强引用;无论何时,只要有强引用关系的对象,都不会被垃圾回收器回收掉,如果内存不足的时候,直接报错
    • 软引用:有软引用关系的对象,当内存即将不足的时候,会被垃圾回收器清理掉;
    • 弱引用:有弱引用关系的对象,只能活到下一次垃圾回收的时候,也就是,只要发生了一次垃圾回收,那么弱引用关系的对象就被清理掉了
    • 虚引用:最弱的引用,我们甚至无法通过虚引用获得关系对象的信息。它的唯一作用,就是在垃圾回收的时候,能够将相关信息放在一个队列中。进而我们可以用这个队列获得相关信息。

    接下来,我们来分别看看这四种引用。

    强引用

    我们平时使用的都是强引用,就比如

    Object o = new Object()

    所以,故不多介绍。

    软引用

    软引用,需要用到 SoftReference 类,这个类的构造方法中放入需要进行软引用的对象。

    package ref;
    
    import java.lang.ref.SoftReference;
    
    public class SoftRefTest {
    
        public static void main(String[] args) {
            SoftReference<String> softReference = new SoftReference<>(new String("Hello World"));
            System.out.println(softReference.get());
    
            System.gc();
            // 根据 老年代 大小进行设置,占满内存
            byte[] bigSize = new byte[1024 * 7168 - 354 * 1024];
            System.out.println(softReference.get());
        }
    }
    

    设置参数

    -Xms10m -Xmx10m -XX:+PrintGCDetails

    可以看到,当我们去占满内存的时候,软引用对象直接被清理掉了。最后获取其引用对象为 null。

    弱引用

    package ref;
    
    import java.lang.ref.WeakReference;
    
    public class WeakRefTest {
        public static void main(String[] args) {
            WeakReference<String> weakReference = new WeakReference<>(new String("Hello World"));
            System.out.println(weakReference.get());
            System.gc();
            System.out.println(weakReference.get());
        }
    }
    

    最后的输出为:

    Hello World
    null
    

    虚引用

    虚引用的使用,与前面有所差距。

    /**
         * Creates a new phantom reference that refers to the given object and
         * is registered with the given queue.
         *
         * <p> It is possible to create a phantom reference with a <tt>null</tt>
         * queue, but such a reference is completely useless: Its <tt>get</tt>
         * method will always return null and, since it does not have a queue, it
         * will never be enqueued.
         *
         * @param referent the object the new phantom reference will refer to
         * @param q the queue with which the reference is to be registered,
         *          or <tt>null</tt> if registration is not required
         */
        public PhantomReference(T referent, ReferenceQueue<? super T> q) {
            super(referent, q);
        }
    

    这是虚引用的构造器,它需要两个参数,一个是对象,另一个对引用队列。

    package ref;
    
    
    import java.lang.ref.PhantomReference;
    import java.lang.ref.ReferenceQueue;
    
    public class PhantomRefTest {
        public static void main(String[] args) throws InterruptedException {
            ReferenceQueue<String> refQueu = new ReferenceQueue<>();
    
            PhantomReference<String> refPhantom = new PhantomReference<>(new String("Hello World"), refQueu);
            System.out.println(refPhantom.get());
    
            System.gc();
            System.out.println(refQueu.remove());
    
        }
    }
    

    最后输出为:

    null
    java.lang.ref.PhantomReference@61bbe9ba
    
  • 相关阅读:
    算法学习记录单链表
    算法学习记录排序
    算法学习记录图——最小生成树之prim算法
    算法学习记录图——应用之拓扑排序(Topological Sort)
    算法学习记录图(DFS BFS)
    算法学习记录排序——冒泡排序(Bubble Sort)
    算法学习记录图——最小路径之Floyd算法
    自用SqlHelper.cs
    WPF的DataGrid的标题加粗样式
    .NET Framework 4.0不能用sqlite的问题解决方法
  • 原文地址:https://www.cnblogs.com/zhouzhiyao/p/13173613.html
Copyright © 2020-2023  润新知