引用文章:Java:强引用,软引用,弱引用和虚引用
建议看看文章,这里做一次总结。
强引用 相当于Object obj=new Object()这种引用就是强引用,即使OOM也不会被垃圾回收器进行回收
软引用 如果将要发生了OOM(内存不够用了)则会将对象自动回收
弱引用 只要发生了gc()就会进行回收虚引用的对象
虚引用 主要用来跟踪对象被垃圾回收的活动。虚引用必须和引用队列关联使用。
案例:
import java.lang.ref.*;
public class WeakReferenceDemo {
public static void main(String[] args) {
softReferenceTest();// 软引用
weakReferenceTest();// 弱引用
}
/**
* 软引用测试案例
* 会发现gc后软引用还能获取"hello world!!!",只有将要OOM的gc才会回收对象那么返回null
*/
private static void softReferenceTest() {
String helloWorldString = new String("hello world!!!"); // 在堆中根据常量字符串创建一个新的字符串对象
SoftReference<String> stringSoftReference = new SoftReference<>(helloWorldString);
System.out.println("打印一下软引用的字符串:" + stringSoftReference.get());//没有进行gc前软引用能得到对象
/**
* 置 null 的作用
* 去除helloWorldString强引用字符串"hello world!!!",
* 因为对象一旦被强引用指向,即使内存不够,宁愿报错也不会被回收改对象,相当于"hello world!!!"原先由两个引用指向这个对象
*/
helloWorldString = null;
System.gc();//进行垃圾回收
stringSoftReference.get();
System.out.println("软引用的字符串被垃圾回收了,得到的字符串是:" + stringSoftReference.get());
}
/**
* 弱引用测试案例
* 会发现gc后,弱引用不能获取"hello world!!!"
*/
private static void weakReferenceTest() {
String helloWorldString = new String("hello world!!!"); // 在堆中根据常量字符串创建一个新的字符串对象
WeakReference<String> stringWeakReference = new WeakReference<>(helloWorldString);// 创建一个弱引用,将弱引用指向堆中的那个字符串
/**
* 置 null 的作用
* 去除helloWorldString强引用字符串"hello world!!!",
* 因为对象一旦被强引用指向,即使内存不够,宁愿报错也不会被回收改对象,相当于"hello world!!!"原先由两个引用指向这个对象
*/
helloWorldString = null;
System.out.println("打印一下弱引用的字符串:" + stringWeakReference.get());//没有进行gc前软引用能得到对象
System.gc();//进行垃圾回收
stringWeakReference.get();
System.out.println("弱引用的字符串被垃圾回收了,得到的字符串是:" + stringWeakReference.get());
}
}
之所以要分成这四种引用,就是在gc的时候被引用的对象是否会被回收内存所分成的情况,以及考虑发生OOM的情况进行gc
强引用: 不用举例子,平时new引用的对象就是强引用
软引用: 可以通过SoftReference<Obj> sr = new SoftReference<Obj>(obj);进行引用,
弱引用: 通过WeakReference<String> sr = new WeakReference<String>(new String("hello"));这个例子使用new创建对象为了避免对象在常量池中。
虚引用: 主要用来跟踪对象被垃圾回收的活动(GCRoot中的引用链应该就是用这个做的,如果一个对象没有被引用GCRoot引用到,则说明这是一个内存垃圾,需要进行垃圾回收)
虚引用的使用例子:
ReferenceQueue<String> queue = new ReferenceQueue<String>();
PhantomReference<String> pr = new PhantomReference<String>(new String("hello"), queue);