强软弱虚引用

强软弱虚,是 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
posted @ 2020-06-21 19:06  土堆碎念  阅读(303)  评论(0编辑  收藏  举报