关于弱引用、软应用、强引用的理解

强引用:只要堆上的对象,被至少一个强引用所指向,那么GC就不会回收该对象的内存空间。
弱引用:只要堆上的对象仅仅只被弱引用所指向,不管当前内存空间是否足够,下次GC都会回收对象的内存空间。
软引用:只要堆上的对象仅仅只被软引用所指向,并且当内存空间不足时,GC才会回收对象的内存空间。

WeakReference 和 SoftReference一般使用在构造一个缓存系统,比如使用一个map来构造。因为缓存系统是一个“全生命期”的对象,系统停止,缓存对象才会被销毁,所以当我们不断的想缓存对象中添加对象时,那么就会导致该缓存对象map所引用的对象越来越多,而因为是强引用,这些被放进map缓存了的对象不能被GC锁回收,那么就导致系统堆内存占用会越来越大,从而最终导致内存溢出。

那么此时我们就可以使用 WeakReference 或 SoftReference了,将强引用通过WeakReference 和 SoftReference 包装之后,变成弱引用和软引用,那么当缓存中的对象,仅仅被缓存map锁引用时,那么分别在下次GC和内存不足GC时就会回收这些对象占用的内存。其实JDK给我们提供了一个专门的类:WeakHashMap ,弱引用的hashMap,所以构造缓存系统是,我们可以考虑使用它。

弱引用事例:

// 构建一个弱引用  
String weakObj = new String("Weak Object");  
ReferenceQueue weakQueue = new ReferenceQueue();  
WeakReference weakReference = new WeakReference(weakObj, weakQueue);  
System.out.println("Weak Reference: " + weakReference.get());  
  
// 清空强引用,并执行垃圾回收  
weakObj = null;  
System.gc();  
System.gc();  
System.gc();  
  
// 检测弱引用是否可用  
// 实验结果:输出结果是null,说明已经被垃圾回收了。  
System.out.println("Weak Reference: " + weakReference.get());

软引用事例:

// 构建一个软引用  
String softObj = new String("Soft Object");  
ReferenceQueue softQueue = new ReferenceQueue();  
SoftReference softRef = new SoftReference(softObj, softQueue);  
System.out.println("Soft Reference: " + softRef.get());  
  
// 清空强引用,并执行垃圾回收  
softObj = null;  
System.gc();  
System.gc();  
System.gc();  
  
// 检测软引用是否可用  
// 输出结果是Soft Object,说明垃圾回收并没有回收软引用。  
System.out.println("Soft Reference: " + softRef.get());   
  
// 申请大量内存,直到内存不足  
LinkedList li = new LinkedList();  
while(true) {  
    try {  
        li.add(new Object[100000]);  
    } catch(OutOfMemoryError e) {  
        break;  
    }  
}  
li = null;  
  
  
// 检测软引用是否可用  
// 实验结果:输出null,说明在内存不足之后软引用已经被系统清理了。  
System.out.println("Soft Reference: " + softRef.get());


你可能感兴趣的:(关于弱引用、软应用、强引用的理解)