Java有四大引用,让开发者去管理对象的生命周期。强引用、软引用、弱引用、软引用。今天就让我们简单的了解一下吧。
强引用:当内存不足时,也不会被回收,所以强引用是造成内存泄漏的原因之一,当强引用对象不使用时,我们应该弱化他,从而使GC能够回收。
软引用:内存足够时,不回收,但是当内存不足时,就会被回收。
弱引用:当垃圾回收器发现它时,它就会被回收。
虚引用:这是一个最虚幻的引用类型 . 无论是从哪里都无法再次返回被虚引用所引用的对象 . 虚引用在系统垃圾回收器开始回收对象时 , 将直接调用 finalize() 方法 , 但不会立即将其加入回收队列 . 只有在真正对象被 GC 清除时 , 才会将其加入 Reference 队列中去 .
当多次运行系统垃圾回收后,IBM JVM 将软引用一并加入了回收队列中,并运行了其 finalize 方法。另外,即使经过很多次系统垃圾回收,虚引用也没有被加入到队列中去。不知道这是不是 IBM JVM 的一个小小的 BUG 所在。
SoftReference 中 Oracle JVM 的表现满足规范,只当内存不足时才进行回收。而 IBM JVM 的策略则更为积极,在内存尚且充足的情况下也进行了回收,值得注意。PhantomReference 中 Oracle JVM 的表现满足规范,执行 finalize 后若干次 GC 就被添加到了 Queue 中。而 IBM JVM 则始终没有被添加到 Queue 中导致了死循环。所以在使用 PhantomReference 时出现类似的情况时,可以考虑是否是因为使用了不同 JVM 所导致。
强引用
向我们平时new的对象都是强引用。
Object wangscaler=new Object();复制代码
因为强引用不会被回收,如果我们的对象不再使用了,可以
wangscaler = null;复制代码
将其弱化,等待垃圾回收时进行回收。
软引用
软引用一般用来做缓存。当内存充足时,将一些数据作为缓存,当内存不够用时,进行回收。像图片处理技术就会将用户上传的图片加入缓存。
SoftReference wangscaler = new SoftReference<>(new Object());复制代码
弱引用
WeakReference wangscaler = new WeakReference();复制代码
弱引用和软引用相似,同样可以用来做缓存,不同的是弱引用的生命周期更短,每次GC的时候,都会被回收,所以应该用于调用频率相对低一些的应用。
虚引用
ReferenceQueue wangscaler = new ReferenceQueue<>();
PhantomReference scaler = new PhantomReference<>(new Object(), wangscaler);复制代码
必须和引用队列一块使用。我们如果有对象被回收时做一些特殊处理,可以采用虚引用。他就像是一种通知机制,和Spring的后置通知一样,告诉我们对象已经被回收了。ThreadLocal底层代码就使用虚引用。值得注意的是虚引用的get()的结果永远都是null,无论有没有被清理,都无法获得到对象。
引用队列
像软引用、弱引用、虚引用三种引用都可以结合引用队列ReferenceQueue一块使用。当三种引用的对象被回收时,加入引用队列,通过引用队列可以了解JVM垃圾回收情况。
对比
总结
使用四种引用来决定对象的生命周期,就像我们日常的生活用品一样,有些物品很快被扔进垃圾桶进行回收,有些物品当家里放不下了就扔出去了,而有些物品什么时候都不能扔,你的存折你扔扔试试。所以当内存不足时,会抛出OutOfMemory异常,也不会将强引用的对象回收。
虚引用有一个很重要的用途就是用来做堆外内存的释放,DirectByteBuffer就是通过虚引用来实现堆外内存的释放的。
更多关于“Java培训”的问题,欢迎咨询千锋教育在线名师。千锋已有十余年的培训经验,课程大纲更科学更专业,有针对零基础的就业班,有针对想提升技术的好程序员班,高品质课程助理你实现java程序员梦想。