• Index

强引用和弱引用

Last updated: ... / Reads: 119 Edit

Java弱引用和强引用的区别?

在Java中,引用是指一个对象的指针或句柄,用来指向内存中的某个对象。Java中有四种类型的引用:强引用、软引用、弱引用和虚引用。

强引用是最常用的引用类型,如果一个对象具有强引用,那么垃圾回收器就不会回收它。只有当一个对象没有任何强引用指向它时,才会被垃圾回收器回收。

相比之下,弱引用的生命周期更短,如果一个对象只有弱引用指向它,那么它随时都可能被垃圾回收器回收。弱引用可以用来实现内存敏感的高速缓存,当缓存中的对象没有被强引用时,垃圾回收器可以自动回收这些对象,避免了内存泄漏。

弱引用可以通过 java.lang.ref.WeakReference 类来创建。例如:

Object referent = new Object();
WeakReference<Object> weakRef = new WeakReference<>(referent);

上面的代码创建了一个弱引用 weakRef,指向对象 referent。当 referent 不再有任何强引用指向它时,垃圾回收器将自动回收它,并且 weakRef.get() 将返回 null。

总结一下:

  1. 强引用:只要存在强引用,垃圾回收器就不会回收对象。
  2. 弱引用:只要没有强引用指向对象,垃圾回收器就可能回收它。
  3. 软引用:只有在内存不足时才会被垃圾回收器回收,通常用来实现缓存。
  4. 虚引用:不能通过引用访问对象,主要用来在对象被回收时收到通知。

弱引用 举例子

以下是一个使用弱引用的例子:

import java.lang.ref.WeakReference;

public class WeakReferenceExample {
    public static void main(String[] args) {
        Object obj = new Object();
        WeakReference<Object> weakRef = new WeakReference<>(obj);
        obj = null; // 让强引用 obj 指向 null,只剩下弱引用指向对象

        // 在弱引用没有被回收前,可以通过弱引用访问对象
        if (weakRef.get() != null) {
            System.out.println("Object is still available via weak reference.");
        }

        // 强制垃圾回收,观察是否会回收弱引用指向的对象
        System.gc();

        // 在弱引用被回收后,不能通过弱引用访问对象
        if (weakRef.get() == null) {
            System.out.println("Object has been garbage collected.");
        }
    }
}

在这个例子中,创建了一个强引用 obj 指向一个对象,然后创建了一个弱引用 weakRef 指向 obj 所指向的对象。然后将 obj 置为 null,只有 weakRef 指向对象。

在弱引用没有被回收之前,可以通过 weakRef.get() 方法访问到对象。但是当调用 System.gc() 方法强制进行垃圾回收时,由于只有弱引用指向对象,对象没有任何强引用指向它,垃圾回收器会回收对象。在弱引用被回收后,通过 weakRef.get() 方法无法再访问到对象,证明对象已经被垃圾回收器回收。

属性是对象类型,是弱引用吗?

属性是对象类型的情况下,并不一定是弱引用,它可能是强引用,也可能是软引用、弱引用、虚引用之一。属性的引用类型取决于它的定义和初始化方式。

例如,在 Java 中,

  1. 如果我们这样定义一个类:
public class MyClass {
    private Object myObj = new Object();
}

那么 myObj 将被定义为一个强引用,因为它没有使用任何引用类型修饰符。

  1. 如果我们使用弱引用来初始化 myObj:
public class MyClass {
    private WeakReference<Object> myObj = new WeakReference<>(new Object());
}

那么 myObj 将被定义为一个弱引用,因为我们明确使用了 WeakReference 类型。

  1. 如果我们使用软引用来初始化 myObj:
public class MyClass {
    private SoftReference<Object> myObj = new SoftReference<>(new Object());
}

那么 myObj 将被定义为一个软引用,因为我们明确使用了 SoftReference 类型。

  1. 如果我们使用虚引用来初始化 myObj:
public class MyClass {
    private PhantomReference<Object> myObj = new PhantomReference<>(new Object(), null);
}

那么 myObj 将被定义为一个虚引用,因为我们明确使用了 PhantomReference 类型。

因此,属性是对象类型,并不一定是弱引用,具体取决于它的定义和初始化方式。


Comments

Make a comment

  • Index