引用文章: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);
-
-