WeakReference与SoftReference
SoftReference(软引用)、WeakReference(弱引用),这两个类是对heap中java对象的应用,通过这个两个类可以和gc做简单的交互。
WeakReference是弱引用,其中保存的对象实例可以被GC回收掉。这个类通常用于在某处保存对象引用,而又不干扰该对象被GC回收,通常用于Debug、内存监视工具等程序中。因为这类程序一般要求即要观察到对象,又不能影响该对象正常的GC过程。
最近在JDK的Proxy类的实现代码中也发现了Weakrefrence的应用,Proxy会把动态生成的Class实例暂存于一个由Weakrefrence构成的Map中作为Cache。
SoftReference是强引用,它保存的对象实例,除非JVM即将OutOfMemory,否则不会被GC回收。这个特性使得它特别适合设计对象Cache。对于Cache,我们希望被缓存的对象最好始终常驻内存,但是如果JVM内存吃紧,为了不发生OutOfMemoryError导致系统崩溃,必要的时候也允许JVM回收Cache的内存,待后续合适的时机再把数据重新Load到Cache中。这样可以系统设计得更具弹性。
强引用
Object o=new Object(); Object o1=o;
上面代码中第一句是在heap堆中创建新的Object对象通过o引用这个对象,第二句是通过o建立o1到new Object()这个heap堆中的对象的引用,这两个引用都是强引用.只要存在对heap中对象的引用,gc就不会收集该对象.如果通过如下代码:
o=null; o1=null;
如果显式地设置o和o1为null,或超出范围,则gc认为该对象不存在引用,这时就可以收集它了。可以收集并不等于就一会被收集,什么时候收集这要取决于gc的算法,这要就带来很多不确定性。例如你就想指定一个对象,希望下次gc运行时把它收集了,那就没办法了,有了其他的两种引用就可以做到了。其他两种引用在不妨碍gc收集的情况下,可以做简单的交互。
heap中对象有强可及对象、软可及对象、弱可及对象、虚可及对象和不可到达对象。应用的强弱顺序是强、软、弱、和虚。对于对象是属于哪种可及的对象,由他的最强的引用决定。如下:
WeakReference
import java.lang.ref.WeakReference; public class WeakReferenceTest { /** * @param args */ public static void main(String[] args) { A a = new A(); a.str = "Hello, reference"; WeakReference<A> weak = new WeakReference<A>(a); a = null; int i = 0; while (weak.get() != null) { System.out.println(String.format("Get str from object of WeakReference: %s, count: %d", weak.get().str, ++i)); if (i % 10 == 0) { System.gc(); System.out.println("System.gc() was invoked!"); } try { Thread.sleep(500); } catch (InterruptedException e) { } } System.out.println("object a was cleared by JVM!"); } }
程序运行结果:
Get str from object of WeakReference: Hello, reference, count: 1 Get str from object of WeakReference: Hello, reference, count: 2 Get str from object of WeakReference: Hello, reference, count: 3 Get str from object of WeakReference: Hello, reference, count: 4 Get str from object of WeakReference: Hello, reference, count: 5 Get str from object of WeakReference: Hello, reference, count: 6 Get str from object of WeakReference: Hello, reference, count: 7 Get str from object of WeakReference: Hello, reference, count: 8 Get str from object of WeakReference: Hello, reference, count: 9 Get str from object of WeakReference: Hello, reference, count: 10 System.gc() was invoked! object a was cleared by JVM!
SoftReference
import java.lang.ref.SoftReference; public class SoftReferenceTest { /** * @param args */ public static void main(String[] args) { A a = new A(); a.str = "Hello, reference"; SoftReference<A> sr = new SoftReference<A>(a); a = null; int i = 0; while (sr.get() != null) { System.out.println(String.format("Get str from object of SoftReference: %s, count: %d", sr.get().str, ++i)); if (i % 10 == 0) { System.gc(); System.out.println("System.gc() was invoked!"); } try { Thread.sleep(500); } catch (InterruptedException e) { } } System.out.println("object a was cleared by JVM!"); } }
总结
SoftReference比WeakReference生命力更强,当JVM的内存不吃紧时,即使引用的对象被置为空了,Soft还可以保留对该对象的引用,此时的JVM内存池实际上还保有原来对象,只有当内存吃紧的情况下JVM才会清除Soft的引用对象,并且会在未来重新加载该引用的对象。
而WeakReference则当清理内存池时会自动清理掉引用的对象。
我是天王盖地虎的分割线
参考:http://wiseideal.iteye.com/blog/1469295
出处:http://yydcdut.cnblogs.com/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?