在应用程序代码内实例化一个类或结构时,只要有代码引用它,就会形成强引用.这意味着垃圾回收器不会清理这样的对象使用的内存.但是如果当这个对象很大,并且不经常访问时,此时可以创建对象的弱引用,弱引用允许创建和使用对象,但是垃圾回收器 运行时,就会回收对象并释放内存.

弱引用是使用WeakReference类创建的.因为对象可能在任何时刻被回收,所以在引用该对象前必须确认它存在.

using System;

namespace ConsoleAppDemo
{
class MathTest
{
public int Value { get; set; } public int GetSquare()
{
return this.Value * this.Value;
}
}
class Program
{
static void Main(string[] args)
{
WeakReference mathReference = new WeakReference(new MathTest());
MathTest math;
if (mathReference.IsAlive)
{
math = mathReference.Target as MathTest;
math.Value = ;
Console.WriteLine("Value field of math variable contains " + math.Value);
Console.WriteLine("Square of 30 is " + math.GetSquare());
}
else
{
Console.WriteLine("Reference is not avaliable.");
}
GC.Collect();
if (mathReference.IsAlive)
{
math = mathReference.Target as MathTest;
Console.WriteLine("Value field of math variable contains " + math.Value);
}
else
{
Console.WriteLine("Reference is not available.");
}
}
}
}

.NET框架提供了另一有趣的特色,被用于实现多样的高速缓存。在.NET中弱引用通过System.WeakReference类实现。弱引用为引用的对象提供一项机制,使被引用的对象能够被垃圾收集器作用。ASP.NET高速缓存就使用了弱引用。如果内存使用率太高,高速缓存将被清除。

强制垃圾收集 .NET框架为开发者提供System.GC类来控制垃圾收集器的一些方面。垃圾收集可以通过调用GC.Collect方法强制执行。通常建议不要手动的调用垃圾收集器,而将其设置为自动方式。在某些情况下,开发者会发现强制垃圾收集将推进性能。但是,使用这个方法需要非常小心,因为在垃圾收集器运行时将延缓当前执行的线程。GC.Collect方法不应位于可能被经常调用的地方。这样做将使应用程序的性能降级。

构造函数:

WeakReference  初始化 WeakReference 类的新实例。 此构造函数重载不能在基于 Silverlight 的应用程序中实现。

WeakReference(Object)  引用指定的对象初始化 WeakReference 类的新实例。

WeakReference(Object, Boolean)  初始化 WeakReference 类的新实例,引用指定的对象并使用指定的复活跟踪。

属性:

IsAlive  获取当前 WeakReference 对象引用的对象是否已被垃圾回收的指示。

Target  获取或设置当前 WeakReference 对象引用的对象(目标)。

TrackResurrection  获取当前 WeakReference 对象引用的对象在终止后是否会被跟踪的指示。

我们考虑使用弱引用的时候:

对象稍后可能被使用,但不是很确定。(如果确定要使用,就应该用强引用)

如果需要,对象可以重新被构造出来(比如数据库构造)。

对象占相对比较大的内存(一般大于几KB以上)

在某些场合,例如缓存某些大数据对象的时候,会遇到内存与时间的两难境况,如果让大对象过快的过期,那么每次创建对象会消耗过多的性能,反之,保持了过多的大对象,那

么内存将耗尽,反而降低速度。 如果内存尚且足够,那么GC就不会回收大对象占用的内存,那么弱引用就是可到达的,也就是说可以重用这个对象,达到缓存的目的。如果内存不足,那么GC就会不得不去回收那些大对象,从而释放内存空间。

下面的代码示例演示如何使用弱引用将对象的缓存作为应用程序的资源进行维护。 此缓存是使用以索引值为关键字的 WeakReference 对象的 IDictionary(Of TKey, TValue) 构建的。 WeakReference 对象的 Target 属性是一个表示数据的字节数组中的对象。

此示例将随机访问缓存中的对象。 如果通过垃圾回收来回收对象,则将重新生成新的数据对象;否则,该对象会因弱引用而可访问。

Cache:

using System;
using System.Collections.Generic; namespace ConsoleAppDemo
{
public class Cache
{
// Dictionary to contain the cache.
static Dictionary<int, WeakReference> _cache; // Track the number of times an
// object is regenerated.
int regenCount = ; public Cache(int count)
{ _cache = new Dictionary<int, WeakReference>(); // Add data objects with a
// short weak reference to the cache.
for (int i = ; i < count; i++)
{
_cache.Add(i, new WeakReference(new Data(i), false));
} } // Returns the number of items in the cache.
public int Count
{
get
{
return _cache.Count;
}
} // Returns the number of times an
// object had to be regenerated.
public int RegenerationCount
{
get
{
return regenCount;
}
} // Accesses a data object from the cache.
// If the object was reclaimed for garbage collection,
// create a new data object at that index location.
public Data this[int index]
{
get
{
// Obtain an instance of a data
// object from the cache of
// of weak reference objects.
Data d = _cache[index].Target as Data;
if (d == null)
{
// Object was reclaimed, so generate a new one.
Console.WriteLine("Regenerate object at {0}: Yes", index.ToString());
d = new Data(index);
regenCount++;
}
else
{
// Object was obtained with the weak reference.
Console.WriteLine("Regenerate object at {0}: No", index.ToString());
} return d;
} } }
}

Data:

namespace ConsoleAppDemo
{
// This class creates byte arrays to simulate data.
public class Data
{
private byte[] _data;
private string _name; public Data(int size)
{
_data = new byte[size * ];
_name = size.ToString();
} // Simple property.
public string Name
{
get
{
return _name;
}
} }
}

Program:

using System;

namespace ConsoleApp
{
class Program
{
static void Main(string[] args)
{
// Create the cache.
int cacheSize = ;
Random r = new Random();
Cache c = new Cache(cacheSize); string DataName = ""; // Randomly access objects in the cache.
for (int i = ; i < c.Count; i++)
{
int index = r.Next(c.Count);
#region 注意这里的代码 如果屏蔽了 就是全部是 yes 没有 就有50%的yes
if (i == )
GC.Collect();
#endregion
// Access the object by
// getting a property value.
DataName = c[index].Name;
}
// Show results.
double regenPercent = c.RegenerationCount * / c.Count;
Console.WriteLine("Cache size: {0}, Regenerated: {1}%", c.Count.ToString(), regenPercent.ToString());
}
}
}

弱引用(WeakReference)的更多相关文章

  1. Android 图片三级缓存之内存缓存(告别软引用(SoftRefrerence)和弱引用(WeakReference))

    因为之前项目同事使用了图片三级缓存,今天整理项目的时候发现同事还是使用了软引用(SoftRefrerence)和弱引用(WeakReference),来管理在内存中的缓存.看到这个我就感觉不对了.脑海 ...

  2. java中的强引用(Strong reference),软引用(SoftReference),弱引用(WeakReference),虚引用(PhantomReference)

    之前在看深入理解Java虚拟机一书中第一次接触相关名词,但是并不理解,只知道Object obj = new Object()类似这种操作的时候,obj就是强引用.强引用不会被gc回收直到gc roo ...

  3. C# 中的弱引用 WeakReference

    C#中的弱引用(WeakReference)   我们平常用的都是对象的强引用,如果有强引用存在,GC是不会回收对象的.我们能不能同时保持对对象的引用,而又可以让GC需要的时候回收这个对象呢?.NET ...

  4. Android学习笔记之SoftReference软引用,弱引用WeakReference

    SoftReference可以用于bitmap缓存 WeakReference 可以用于handler 非静态内部类和匿名内部类容易造成内存泄漏 private Handler mRemoteHand ...

  5. 说说WeakReference弱引用

    WeakReference弱引用概述 http://www.cnblogs.com/xrq730/p/4836700.html,关于Java的四种引用状态具体请参看此文 Java里一个对象obj被创建 ...

  6. 理解Java中的弱引用(Weak Reference)

    本篇文章尝试从What.Why.How这三个角度来探索Java中的弱引用,理解Java中弱引用的定义.基本使用场景和使用方法.由于个人水平有限,叙述中难免存在不准确或是不清晰的地方,希望大家可以指出, ...

  7. Java之强引用、 软引用、 弱引用、虚引用

    1.强引用 平时我们编程的时候例如:Object object=new Object();那object就是一个强引用了.如果一个对象具有强引用,那就类似于必不可少的生活用品,垃圾回收器绝不会回收它. ...

  8. Java 引用 WeakReference

    Reference 是一个抽象类,而 SoftReference,WeakReference,PhantomReference 以及 FinalReference 都是继承它的具体类.接下来我们来分别 ...

  9. Java中的强引用和弱引用

    旭日Follow_24 的CSDN 博客 ,全文地址请点击: https://blog.csdn.net/xuri24/article/details/81114944 一.强引用 如下是强引用的经典 ...

随机推荐

  1. JQUERY-定义-查找

    正课: 1. 什么是jQuery 2. 如何使用jQuery 3. 查找 1. 什么是jQuery 第三方开发的 执行DOM操作的 极简化的 函数库 第三方: 下载 执行DOM操作: 学习jQuery ...

  2. ABP框架系列之四:(Repositories-仓库)

    "Mediates between the domain and data mapping layers using a collection-like interface for acce ...

  3. 第38章:MongoDB-集群--Replica Sets(副本集)---多机的搭建

    ①机器环境 182.48.115.236    master-node(主节点) 182.48.115.237    slave-node1(从节点) 182.48.115.238    slave- ...

  4. 小程序快捷键(mac中)

    快捷键 格式调整  - Ctrl+S:保存文件  - Ctrl+[, Ctrl+]:代码行缩进  - Ctrl+Shift+[, Ctrl+Shift+]:折叠打开代码块  - Ctrl+C Ctrl ...

  5. Nginx Redirect Websocket

    I want to redirect my websocket to another server. As we known, nginx command rewrite or redirect ca ...

  6. _ZNote_Qt_QtCreator_Tips_粘贴_历史剪切板

    发现 快捷键 Shift+Command + V 能够出现历史剪切板. 厉害了我的歌

  7. Android Studio导入项目一直卡在Building gradle project info的解决方案

    出现了一个很神奇的现象,Android Studio导入其它项目均正常,但是导入某个项目(两天前还正常打开的项目)却一直卡在Building gradle project info 尝试了重启Andr ...

  8. Visual Studio 2013 配置多个Release版本,并为每个版本配置预编译的宏

    最近开发过程中,需要将同一份工程编译成两个版本,分别为ReleaseA和ReleaseB. ReleaseB比ReleaseA少了部分功能,所以希望在编译的时候,根据不同的版本编译工程中相应的代码. ...

  9. GitHub(从安装到使用)

    一.安装Git for Windows(又名msysgit)  下载地址: https://git-for-windows.github.io/  在官方下载完后,安装到Windows Explore ...

  10. 前端学习之路-CSS介绍,Html介绍,JavaScript介绍

    CSS介绍 学前端必备掌握CSS样式,css为层叠样式表,用来定义页面的显示效果,加强用户的体验乐趣,那么如何用css到html中呢? style属性方式 利用标签中的style属性来改变显示样式 & ...