声明:本篇博客翻译自:http://tipsandtricks.runicsoft.com/CSharp/WeakReferences.htmlhtml
因为水平(技术水平+英语理解能力)有限/不足,确定会有所疏漏/错误,请及时指正。性能
在平常开发中,一般会遇到一些大对象的处理。这些大对象一般在整个程序中屡次使用。例如:大文件对象,大的字典类。一般状况下咱们会使用下面的方式:spa
做为一个方法的内置本地变量;翻译
做为一个类的字段存在;code
这两种方式都不是很好。做为一个类的字段,类的实例将一直持有这个大对象,消耗不少内存;做为一个方法的本地变量使用,当方法执行完毕,这个大对象离开了做用域,但此时不必定会被GC直接回收。形成没必要要的内存消耗。且每次调用该方法时,会从新建立新的大对象,增长程序的内存消耗。htm
若是建立对象很消耗资源,且咱们想要避免屡次建立同一个对象。可使用类的字段方式。对象
一般状况下,当一个对象离开了做用域,或者被设置为null。咱们将没法访问到它。.NET提供了一个WeakReference类,能够完美的解决这个问题。blog
WeakReference对象将保存一个对象的引用即便这个对象已经离开了做用域或者被设置为null了,经过WeakReference还能够访问到这个对象。除非被GC回收掉了,WeakReference对象此时没法访问到该对象。ip
WeakReference的使用很是简单,内存
MyHugeObject hugeObject = new MyHugeObject(); WeakReference w = new WeakReference(hugeObject);
经过WeakReference的Target属性能够得到关联的对象,
MyHugeObject = w.Target as MyHugeClass;
若是这个对象仍然存在,经过Target属性能够得到到。若是对象已经被GC回收了,Target获得的值为null
static void Func() { MyHugeClass MyHugeObject; if ( (w == null) || ( (MyHugeObject=w.Target as MyHugeClass) == null) ) { MyHugeObject = new MyHugeClass(); w = new WeakReference(MyHugeObject); } // work with MyHugeObject }
WeakReference提供给咱们很大的好处:它将保持MyHugeObject的引用,而且确保能够在没有被GC回收的状况下从新获得该对象,且不用担忧从新得到的对象是不完整的或者被损坏的。
PS:使用WeakReference并不能保证提升程序的性能,大多数状况下相比于使用本地局部变量而言性能会有所提升。可是不作任何担保。一些状况下还会出现更多的程序性能消耗,例如一个大对象关联了许多小对象,此时会将这些小对象也转成Weak Reference。此时会对GC内存回收有损耗。
参考连接:
https://docs.microsoft.com/en-us/dotnet/standard/garbage-collection/weak-references
http://tipsandtricks.runicsoft.com/CSharp/WeakReferences.html
https://msdn.microsoft.com/en-us/library/system.weakreference(v=vs.110).aspx