java中存在四种引用机制,分别是强引用,软引用,弱引用,虚引用
强引用
一般情况下我们用new方式创建的引用就是强引用,比如
Client client = new Client()
jvm进行GC的时候是不会回收存在强引用的对象的,比如
Server server = new Server()
Client client = new Client()
当在第二行时jvm内存耗尽,jvm会报内存溢出的错误,也不会去回收第一行的对象
只有当存在强引用的方法块执行完毕或者手动将强引用设置为null,这样才有可能被垃圾回收器回收掉
软引用
如果一个对象具有软引用,内存空间足够,垃圾回收器就不会回收它;
如果内存空间不足了,就会回收这些对象的内存。只要垃圾回收器没有回收它,该对象就可以被程序使用。
软引用可用来实现内存敏感的高速缓存,比如网页缓存、图片缓存等。使用软引用能防止内存泄露,增强程序的健壮性。
我们使用SoftReference实例来保存一个对象的软引用,比如
MyObject aRef = new MyObject();
SoftReference aSoftRef=new SoftReference(aRef);
aSoftRef就是aRef的软引用,如果我们将
aRef==null
此时当内存不足jvm进行GC时就会将aSoftRef清除掉,使用
MyObject anotherRef=(MyObject)aSoftRef.get();
会重新获得强引用对象,如果软引用对象已经被GC清楚,则返回null,我们可以利用软引用实现一些缓存功能
当第一次从数据库加载数据的时候将对象设置一个软引用,当对象使用完毕,GC还没有清理的时候再次加载对象时,
可以先从软引用队列查找是否存在跟对象相关的软应用,如果存在则调用get方法获取该对象的强引用,否则再去数据库加载
说到软引用队列ReferenceQueue,往往是结合软引用使用,当软引用的对象被清除以后往往软引用本身的引用也就没有存在的价值了,此时需要
一个场景来记录所以软引用,然后轮询这清除这些软引用,此时会选择将软引用加入软引用队列,然后如果软引用的get方法返回Null时则清除改软引用
弱引用
弱引用与软引用相似,不同的时jvm在GC时会直接将存在弱引用的对象清除,而不是在内存不足时才开始清除,所以相比软引用被GC的几率更大
虚引用
需引用往往是发生在finalize之后,与前几种引用不同的是,具有虚引用的对象是无法转换为强引用被调用的,它更像是一个finalize方法的记录,可以通过查找虚引用判断对象是否要被GC回收,以及相关资源是否在finalize的时候被关闭等