开发者社区> 技术小甜> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

弱引用研究

简介:
+关注继续查看

通常的,当说起对象引用的时候,一般指的是强引用,即只要这个对象还是可达状态(还会被程序访问到),那么垃圾回收器就不会去回收它。

而弱引用的对象被认为是不可达的,但它可以由应用程序访问,同时还能被垃圾回收器收回。支持垃圾收集的语言大多都支持弱引用,例如Java,C#,Python等。

通常,弱引用特别适合以下对象:占用大量内存,但通过垃圾回收功能回收以后很容易重新创建。C#中使用WeakReference类来创建弱引用对象。

下面是示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public string FilePath = "PathToMyImportantFile.dat";
       public WeakReference WeakRef = new WeakReference(null);
       public object ImportantBigFileContents
       {
           get
           {
               object bigObject = WeakRef.Target;
               if (bigObject == null)// 该弱引用已经被回收了,那么就变成null,则需要构造大对象。
               {
                   using (StreamReader r = new StreamReader(FilePath))
                       bigObject = r.ReadToEnd();
                   WeakRef.Target = bigObject;
               }
               return bigObject;
           }
       }

假设ImportantBigFileContents是某一个类的属性,该属性值是一个很占内存的对象,那么可以考虑使用弱引用存储这个大对象。

如果弱引用中的Target属性中的值仍然存在,则直接获取这个值返回。如果这个值已经被垃圾回收器回收掉了,那么这个值就是null。因此需要重新构造出该大对象。

注意,垃圾回收器究竟再何时启动,程序员是没法掌控的,因此也不能确定弱引用对象何时被回收。所以,很容易犯如下的错误,比如如下代码:

1
2
3
4
5
6
7
8
9
10
public object ImportantBigFileContents
       {
           get
           {
               if (WeakRef.Target == null)
                   using (StreamReader r = new StreamReader(FilePath))
                       WeakRef.Target = r.ReadToEnd();
               return WeakRef.Target;
           }
       }

看上去没啥错误,如果WeakRef.Target属性为null则构造出大对象,如果WeakRef.Target有值则返回该值。

但是这里有一个小概率事情,由于垃圾回收器是异步执行的,你不会知道啥时回收,有一种可能是要调用return WeakRef.Target;句子前回收了。这样的话就会导致返回null。因此,推荐的做法是在读取弱引用对象之前,还是把它放入强引用对象中,即放入一个普通的对象中去。

弱引用还可以用来处理内存泄露的风险,例如常见的垃圾回收算法是引用计数,引用计数法计算了对象被引用的次数,在被引用的次数为0的时候,回收该对象。但是对于环形引用的对象,无法回收。即比如A中对象引用了B对象,B对象中也引用了A对象,这种情况下,垃圾回收器无法回收A对象和B对象,一旦这种环形引用的多了之后,就会引发内存泄露。

如果把A对象和B对象都设成弱引用的话,GC在必要的时候还是会收回资源的。

但是同时也要避免对小对象使用弱引用,因为指针本身可能和对象一样大,或者比对象还大。事实上,如果内存不是那么紧张的话,也没必要过度的使用弱引用。















本文转自cnn23711151CTO博客,原文链接: http://blog.51cto.com/cnn237111/1243849,如需转载请自行联系原作者

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
「技术翻译」JVM研究系列「绝版敲门砖」带你进入JVM-ZGC垃圾回收器的时代和未来
「技术翻译」JVM研究系列「绝版敲门砖」带你进入JVM-ZGC垃圾回收器的时代和未来
0 0
关于垃圾收集器你了解多少?一文总结七大垃圾收集器
如果说垃圾收集算法是内存回收的理论,那么垃圾收集器就是内存回收的具体实现。 垃圾收集器目前存在的有很多,但是依旧没有哪个收集器是万能的存在,我们只能选择一个最适合应用的收集器。
0 0
老徐和阿珍的故事:强引用、软引用、弱引用、虚引用,傻傻分不清楚
阿珍:“老徐,你这茶杯了泡的什么?红红的。” 老徐:“这是枸杞呀。” 阿珍:“枸杞?你最近什么干多了,这么虚!” 老徐:“怎么可能?看我这身体,不弱的好吧!” 阿珍一脸坏笑地说:“那就是软了。” 老徐的老脸一红,辩解到:“我这是养养生,我很强的,好吧。” 看着老徐的窘态,阿珍笑出来声。老徐起身刚要走,阿珍一把拽住老徐,说:“跟你开玩笑呢,问你个正事,我一直分不清Java的强引用、软引用、弱引用、虚引用,给我讲讲呗。” 老徐立刻自信满满的坐下,说:“那你可问对人了,我对这方面颇有研究。这四种引用级别由高到低依次是:强引用、软引用、弱引用、虚引用。”
0 0
细数 ThreadLocal 三大坑,内存泄露仅是小儿科
我在参加Code Review的时候不止一次听到有同学说:我写的这个上下文工具没问题,在线上跑了好久了。其实这种想法是有问题
0 0
关于Java的软引用及弱引用
概念介绍   1   Reference      描述一个对象的引用。其内部维持一个queue引用,用于跟踪对象的回收情况,当对象被回收时将当前reference引用入队   2   SoftReference      软引用,仅当JVM内存紧张时会回收关联对象,即JVM在抛出OOM异常之前会回收所有的SoftReference关联的对象。
635 0
IE内存泄露与无法回收研究小结
一、内存泄露    之前确实看了很多资料,但这位大哥的话可谓画龙点睛,不是奉承他,一下子就打通了我的任督二脉,请看: trarck 写道    IE下的内存泄露原因就是循环引用,IE的垃圾回收器不能很好处理这种引用。
810 0
有关 SoftReference 的一些事实
Java 的 SoftReference 有很多年都没有被人惦记了。在 Javadoc 里, 它的描述是这样:   ”虚拟机在抛出 OutOfMemoryError 之前会保证所有的软引用对象已被清除。
836 0
转贴经典例子:弱引用 WeakReference
在程序设计中我们经常会进行一些全局缓存设计,诸如使用静态或者全局根字段来引用某个对象,以便一次创建多次使用。如:   class BigData  {  }  class Program  {    static BigData cache;    public static BigData DataCache    {      get       {        if (cache==
1107 0
+关注
文章
问答
文章排行榜
最热
最新
相关电子书
更多
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载
冬季实战营第三期:MySQL数据库进阶实战
立即下载