看过很多讲java里引用的文章,但大多都是告诉你,弱引用是当java gc发生的时候,就会进行回收,软引用是内存不足的时候进行回收等等。但这样总感觉有点抽象。前几天看到一篇文章,里面的代码引起了我的兴趣。我在原文代码的基础上做了一些改动,这样或许可以对软引用和弱引用有更好的理解。文章原文可以点击这里查看
弱引用的相关概念这里就不过多探讨了,网上有很多,我们直接上代码
public class WeakestRef {
//coding starts from here
public void something()
{
System.out.println("This is printed out on the screen");
}
}
public static void main(String[] args) {
// Strong Reference
WeakestRef obj1 = new WeakestRef ();
obj1.something();
// Creating Weak Reference to WeakestRef -type object to which 'obj1' is also pointing.
WeakReference< WeakestRef > weakref = new WeakReference< WeakestRef >(obj1);
//Now, WeakestRef -type object to which 'obj1' was pointing earlier is not available for garbage collection. But will be only be garbage collected when JVM needs memory.
obj1= null;
// Note: You can also retrieve back the object which has been weakly referenced. It succesfully calls the method.
obj1= weakref.get();
obj1.something();
}
上面这两段是原文里的代码,打印出来的结果是
This is printed out on the screen
This is printed out on the screen
作者的意思可能是当一个对象是弱引用的时候,你把他置空,但他不会立即被垃圾回收器回收,只有JVM需要内存,需要进行垃圾清理的时候才会被回收。如果你没觉得这段代码没有什么问题,那么请继续往下看
现在,让我对这段代码进行一些改动,改动成下面这样:
public static void main(String[] args) {
WeakestRef obj1 = new WeakestRef();
obj1.something();
WeakReference<WeakestRef> weakref = new WeakReference<WeakestRef>(obj1);
obj1 = null;
//手动调用gc
System.gc();
obj1 = weakref.get();
obj1.something();
}
我在把对象置空之后,加了一段手动调用gc的代码,那么打印出来的结果就变了,
This is printed out on the screen
Exception in thread "main" java.lang.NullPointerException
at Main.main(Main.java:21)
这或许证实了WeakReference只要发生gc,那么就会被回收的说法。那么如果把WeakReference换成SoftReference,会发生什么呢?
public static void main(String[] args) {
WeakestRef obj1 = new WeakestRef();
obj1.something();
//WeakReference变为SoftReference
SoftReference<WeakestRef> weakref = new SoftReference<WeakestRef>(obj1);
obj1 = null;
//手动调用gc
System.gc();
obj1 = weakref.get();
obj1.something();
}
我把WeakReference变为了SoftReference,那么打印的结果就变成了:
This is printed out on the screen
This is printed out on the screen
这或许也印证了,软引用只有在内存不足的时候才会被垃圾回收期回收。我编译的环境是基于openjdk11。这两段代码的结果和大多数讲weakReference和softReference的文章所表达的是一样的,只是更加直观一些。希望对其他不是很理解weakReference和softReference的人有所帮助