扫二维码与项目经理沟通
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流
通常的,当说起对象引用的时候,一般指的是强引用,即只要这个对象还是可达状态(还会被程序访问到),那么垃圾回收器就不会去回收它。
创新互联服务项目包括抚顺网站建设、抚顺网站制作、抚顺网页制作以及抚顺网络营销策划等。多年来,我们专注于互联网行业,利用自身积累的技术优势、行业经验、深度合作伙伴关系等,向广大中小型企业、政府机构等提供互联网行业的解决方案,抚顺网站推广取得了明显的社会效益与经济效益。目前,我们服务的客户以成都为中心已经辐射到抚顺省份的部分城市,未来相信会继续扩大服务区域并继续获得客户的支持与信任!而弱引用的对象被认为是不可达的,但它可以由应用程序访问,同时还能被垃圾回收器收回。支持垃圾收集的语言大多都支持弱引用,例如Java,C#,Python等。
通常,弱引用特别适合以下对象:占用大量内存,但通过垃圾回收功能回收以后很容易重新创建。C#中使用WeakReference类来创建弱引用对象。
下面是示例代码:
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。因此需要重新构造出该大对象。
注意,垃圾回收器究竟再何时启动,程序员是没法掌控的,因此也不能确定弱引用对象何时被回收。所以,很容易犯如下的错误,比如如下代码:
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在必要的时候还是会收回资源的。
但是同时也要避免对小对象使用弱引用,因为指针本身可能和对象一样大,或者比对象还大。事实上,如果内存不是那么紧张的话,也没必要过度的使用弱引用。
另外有需要云服务器可以了解下创新互联scvps.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流