在 Java 中,引用类型指向的数据在堆中分配,而基本类型的变量和对象的引用变量存储在栈内存中,但引用类型实际的对象存储在堆内存中。
Java 中有以下四种引用类型:
强引用(Strong Reference):
Java中默认声明的就是强引用,它是最常用的引用类型
,只要强引用存在,那么垃圾回收器将永远不会回收被引用的对象。如果想被回收,可以将对象置为null。
比如,使用 new
关键字创建的对象,所产生的引用就是强引用,例如:
// 强引用 Object obj = new Object();
软引用(Soft Reference):
在内存足够的时候,软引用不会被回收,软引用在系统内存不够时,才会被垃圾回收器回收。
当垃圾回收器决定要回收内存时,只会回收软引用对象所指向的堆内存对象,并且只有在内存不足时才会进行回收,如果回收了软引用对象之后仍然没有足够的内存,就会出现内存溢出异常
。例如:
// 软引用 SoftReference<Object> softRef = new SoftReference<Object>(obj);
弱引用(Weak Reference):
弱引用不会阻止其所指向的对象被回收
。当垃圾回收器扫描到弱引用时,无论 JVM 内存是否足够,都会将引用指向的对象回收,例如:
// 弱引用 WeakReference<Object> weakRef = new WeakReference<Object>(obj);
虚引用(Phantom Reference):
最弱的引用类型,虚引用不能单独使用
,必须和引用队列(ReferenceQueue)结合使用。
当垃圾回收器把一个对象回收时,如果这个对象有一个虚引用,则会将这个虚引用加入到与之关联的引用队列中,程序可以通过判断引用队列中是否加入了引用,来判断被引用的对象是否将要被垃圾回收,这样可以在对象被回收之前采取一些必要的措施
例如:
// 虚引用 PhantomReference<Object> phantomRef = new PhantomReference<Object>(obj, queue);
Java 中的引用类型都可以通过一些工厂方法创建,比如 java.lang.ref.SoftReference
、java.lang.ref.WeakReference
和 java.lang.ref.PhantomReference
,这些引用类型可以有效地管理内存,避免内存泄漏。