C#中考虑为大对象使用弱引用
1.无论怎样尽力,我们总是会使用到某些需要大量内存的数据,而这些内存并不需要经常访问。或许你需要从一个大文件中查找某个特定的值,或者算法需要一个较大的查询表。这时,你也许会采用2中不太好做法:第一种是创建一个本地变量,然后在每次执行该算法时都生成一大块垃圾;第二种则是创建一个成员变量,在很长一段时间内都占用着这一大块内存。很多时候这两种做法都不是非常好。
2.有没有一种好的选择来处这个问题呢?答案是创建弱引用,弱引用的对象和垃圾对象差不多,程序会告诉垃圾收集器该对象可以被回收,不过在回收之前你仍旧有一个引用,可以用来在需要的时候访问到该对象。若能合理使用该策略,弱引用将和垃圾收集器协同工作,从而优化内存使用。如下代码说明:
/// <summary>
/// 大对象类型
/// </summary>
public class MyLargeClass
{
private int[,] matrix;
private ushort matrixXDimension;
private ushort matrixYDimension;
public string reallyLongMessage; private static WeakReference _weakObj;
public static object WeakObj
{
get
{
return _weakObj?.Target;//“?.”语法为C#6.0的新特性,对应.Net Framework 4.6。表示若为空则返回空,若不为空则获取其相应的属性值
}
set
{
_weakObj = new WeakReference(value);//弱引用的创建
}
} public MyLargeClass(ushort matrixXDimension, ushort matrixYDimension)
{
this.matrixXDimension = matrixXDimension;
this.matrixYDimension = matrixYDimension;
matrix = new int[matrixXDimension, matrixYDimension];
} private void Initialize()
{
//TODO 做更多的数据初始化
//对matrix二维数组的数据加载
} public long Calculate()
{
//TODO 处理对matrix对象计算结果
return matrixXDimension * matrixYDimension * ;
} public static void Execute()
{
//从弱引用中获得大对象,若没有弱引用或弱引用已被回收,此时就需要重新创建对象。
MyLargeClass myLargeObject = WeakObj as MyLargeClass;//myLargeObject可为本地变量,也可为成员变量
if (myLargeObject == null)
{
myLargeObject = new MyLargeClass(, );
}
//TODO 对myLargeObject对象中的数据进行处理 //处理完成后,把大对象归到弱引用,然后把myLargeObject设置为null,表明大对象无引用。此时,系统会认为myLargeObject所指向的对象可以被垃圾收集。若垃圾收集器在此时运行,那么将会回收该对象。不过若是在回收之前,你再次需要该对象,只需如上面的4行代码处理即可。
WeakObj = myLargeObject;
myLargeObject = null;
}
}
3.从上面的Execute()方法的2处代码中,可以看出对象的使用与清理交给了运行时处理,这是简单的使用场景,不过很多时候现实并不是那么简单,很少有对象会完全与外界隔离。任何一个大对象都包含了对其他对象的引用。若一个大对象被标记为弱引用,则其内部引用对象也将被标记为弱引用。被标记的弱引用对象就会被回收(不是马上回收)。
4.对于实现了IDisposable的对象,则不应该使用弱引用,因为被释放的对象已经不能再弱引用,且在弱引用中你也不能调用Dispose()。所以弱引用应该配合非IDisposable的大对象使用。
C#中考虑为大对象使用弱引用的更多相关文章
- weakref:对象的弱引用
介绍 weakref支持对象的弱引用,正常的引用会增加对象的引用计数,并避免它被垃圾回收.但结果并不是总和期望的那样,比如有时候可能会出现一个循环引用,或者有时候需要内存时可能要删除对象的缓存.而弱引 ...
- HTML5中的二进制大对象Blob(转)
HTML5中的Blob对象和MYSQL中的BLOB类型在概念上是有点区别的.MYSQL中的BLOB类型就只是个二进制数据容器.而HTML5中的Blob对象除了存放二进制数据外还可以设置这个数据的MIN ...
- Java -强引用&弱引用
⑴强引用(StrongReference) 就是通过new得的对象引用 强引用是使用最普遍的引用.如果一个对象具有强引用,那垃圾回收器绝不会回收它.当内存空间不足,Java虚拟机宁愿抛出OutOfMe ...
- Java基础 之软引用、弱引用、虚引用 ·[转载]
Java基础 之软引用.弱引用.虚引用 ·[转载] 2011-11-24 14:43:41 Java基础 之软引用.弱引用.虚引用 浏览(509)|评论(1) 交流分类:Java|笔记分类: Ja ...
- [翻译] 编写高性能 .NET 代码--第二章 GC -- 减少大对象堆的碎片,在某些情况下强制执行完整GC,按需压缩大对象堆,在GC前收到消息通知,使用弱引用缓存对象
减少大对象堆的碎片 如果不能完全避免大对象堆的分配,则要尽量避免碎片化. 对于LOH不小心就会有无限增长,但LOH使用的空闲列表机制可以减轻增长的影响.利用这个空闲列表,我们可以在两块分配区域中间找到 ...
- 九、Android学习笔记_ Android开发中使用软引用和弱引用防止内存溢出
在<Effective Java 2nd Edition>中,第6条“消除过期的对象引用”提到,虽然Java有 垃圾回收机制,但是只要是自己管理的内存,就应该警惕内存泄露的问题,例如的对象 ...
- java对象的四种引用:强引用、软引用、弱引用和虚引用
在JDK1.2之前,创建的对象只有在处于可触及(reachable)的状态下,才能被程序使用.也就是说,若一个对象不被任何变量引用,那么程序就无法再使用这个对象.垃圾回收器一旦发现这些无用对象,就会对 ...
- Android学习笔记_78_ Android开发中使用软引用和弱引用防止内存溢出
在<Effective Java 2nd Edition>中,第6条“消除过期的对象引用”提到,虽然Java有 垃圾回收机制,但是只要是自己管理的内存,就应该警惕内存泄露的问题,例如的对象 ...
- 谈谈Java对象的强引用,软引用,弱引用,虚引用分别是什么
整体结构 java提供了4中引用类型,在垃圾回收的时候,都有自己的各自特点. 为什么要区分这么多引用呢,其实这和Java的GC有密切关系. 强引用(默认支持模式) 把一个对象赋给一个引用变量,这个引用 ...
随机推荐
- Spring-Context之六:基于Setter方法进行依赖注入
上文讲了基于构造器进行依赖注入,这里讲解基于Setter方法进行注入.在Java世界中有个约定(Convention),那就是属性的设置和获取的方法名一般是:set+属性名(参数)及get+属性名() ...
- PHP面向对象06_异常处理
oop06异常处理 2014-9-2 8:36:33 NotePad++ By jiancaigege 摘要: 1.异常处理 2.类中常用函数 异常处理 语法格式: try{ //捕获异常 }catc ...
- DNS正向解析与反向解析
DNS:(Domain Name System,域名系统),因特网上作为域名和IP地址相互映射的一个分布式数据库,能够使用户更方便的访问互联网, 而不去记住能够被机器直接读取的IP数串.通过主机名,最 ...
- js显示yyyy年mm日dd天 星期几 的格式日期
js代码: <script type="text/javascript"> var today = new Date(); var week; //存储星期几 var ...
- 转载:Spring AOP (下)
昨天记录了Spring AOP学习的一部分(http://www.cnblogs.com/yanbincn/archive/2012/08/13/2635413.html),本来是想一口气梳理完的.但 ...
- 打开android虚拟机时出现a repairable android virtual device
打开android虚拟机时出现a repairable android virtual device,虚拟机可以打开但是一直处于开机状态,具体解决方案如下: 解决方案1:换个版本,不要选 CPU/AB ...
- 了解HTML表单之input元素的23种type类型
目录 传统类型 text password file radio checkbox hidden button image reset submit 新增类型 color tel email url ...
- java中对象的初始化过程
class Parent{ int num = 8;// ->3 Parent(){ //super(); // ->2 //显示初始化 // ->3 //构造代码段 // -> ...
- poj 2777(线段树的节点更新策略)
/* 之前的思想是用回溯的方式进行颜色的更新的!如果用回溯的方法的话,就是将每一个节点的颜色都要更新 通过子节点的颜色情况来判断父节点的颜色情况 !这就是TLE的原因! 后来想一想没有必要 !加入[a ...
- js获取url地址中的参数
<script type="text/javascript"> function GetQueryString(name) { var reg = new RegExp ...