java的弱引用、软引用和虚引用

Java中的弱引用、软引用和虚引用是用于解决内存泄漏问题的引用类型。它们具有不同的特性,可以在不同场景下使用。

1. *弱引用(WeakReference)

弱引用用于引用对象,但不影响对象的垃圾回收。当系统内存空间不足时,JVM会优先回收被弱引用引用的对象。弱引用可以和一个引用队列(ReferenceQueue)联合使用,当被引用的对象被垃圾回收时,就会将弱引用对象加入到引用队列中。

示例代码:

import java.lang.ref.WeakReference;
import java.lang.ref.ReferenceQueue;

public class WeakReferenceExample {
    public static void main(String[] args) {
        String str = new String("Hello");
        ReferenceQueue<String> queue = new ReferenceQueue<>();
        WeakReference<String> weakRef = new WeakReference<>(str, queue);
        str = null; // 显式将强引用设置为null,使对象成为垃圾
        System.gc(); // 显式调用垃圾回收器
        try {
            // 如果弱引用对象被加入引用队列,说明被引用的对象已经被回收
            if (queue.remove(1000) != null) {
                System.out.println("The object has been garbage collected.");
            } else {
                System.out.println("The object is still alive.");
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

2. 软引用(SoftReference)

软引用用于引用对象,只有当系统内存不足时,才会回收被软引用引用的对象。软引用同样可以和一个引用队列联合使用。软引用常用于实现内存敏感的缓存。

示例代码:

import java.lang.ref.SoftReference;
import java.lang.ref.ReferenceQueue;

public class SoftReferenceExample {
    static class HeavyObject {
        private byte[] spaceHolder = new byte[1024 * 10]; // 占用一定的内存空间
    }
    
    public static void main(String[] args) {
        HeavyObject heavyObj = new HeavyObject();
        ReferenceQueue<HeavyObject> queue = new ReferenceQueue<>();
        SoftReference<HeavyObject> softRef = new SoftReference<>(heavyObj, queue);
        heavyObj = null; // 显式将强引用设置为null,使对象成为垃圾
        // 在内存充足的情况下,对象不会被回收
        System.out.println("Is the object alive? " + (softRef.get() != null));
        // 模拟内存不足的情况,触发垃圾回收
        byte[] memoryFiller = new byte[1024 * 1024 * 100]; // 分配大量内存空间
        System.out.println("Is the object alive? " + (softRef.get() != null)); // 对象可能被回收了
    }
}

3. 虚引用(PhantomReference)

虚引用是最弱的一种引用关系。一个对象是否有虚引用的存在,完全不会对其生存时间构成影响,也无法通过虚引用来获取一个对象实例。唯一的用处就是能在这个对象被收集器回收时收到一个系统通知。虚引用必须和引用队列联合使用,其主要作用是跟踪对象被垃圾回收的活动。虚引用与软引用和弱引用的一个区别在于:虚引用必须和引用队列(ReferenceQueue)联合使用,如果虚引用所引用的对象被垃圾回收,就会将虚引用加入到引用队列中,而不会像软引用和弱引用那样直接置为null。

由于虚引用不会影响对象的生存时间,也不能通过虚引用来获取对象实例,因此其示例代码与弱引用和软引用的示例代码类似,只是将WeakReferenceSoftReference替换为PhantomReference即可。

你可能感兴趣的:(Java,java,jvm)