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

弱引用是使用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. 别人的Linux私房菜(11)认识与学习BASH

    Linux下使用BASH   Bourne Again Shell        另外一种由用于Unix的伯克利大学的Bill Joy设计的C Shell 系统中合法的shell会写入到/etc/sh ...

  2. 20175316盛茂淞 2018-2019-2 《Java程序设计》第2周学习总结

    20175316盛茂淞 2018-2019-2 <Java程序设计>第2周学习总结 教材学习内容总结 1.整数:可细分为为short整数(占2字节),int整数(占4字节),long整数( ...

  3. 子div撑不开父div

    方法一:推荐 设置父div的overflow:hidden; 方法二: 父div结束前增加一个空div style=”clear:both;” .clear { clear:both; } <d ...

  4. js-function复制变量值和传递参数

    <title>function复制变量值</title></head><body> <script> var a={ num:10 } // ...

  5. 冲刺博客NO.10

    今天做了什么:将程序整合到一起,出现了不少小错误,但是在讨论后都解决了. 遇到的难题:没遇到什么大困难

  6. 背水一战 Windows 10 (70) - 控件(控件基类): UIElement - Transform3D(3D变换), Projection(3D投影)

    [源码下载] 背水一战 Windows 10 (70) - 控件(控件基类): UIElement - Transform3D(3D变换), Projection(3D投影) 作者:webabcd 介 ...

  7. 3.html基础标签:表格

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  8. 从零开始的程序逆向之路 第一章——认识OD(Ollydbg)以及常用汇编扫盲

    作者:Crazyman_Army 原文来自:https://bbs.ichunqiu.com/thread-43041-1-1.html 0×00 序言: 1.自从上次笔者调戏完盗取文件密码大黑客后, ...

  9. 我自己的sublime3环境

    概述 我本来一直用的别人自带的破解版sublime3,自带插件. 前几天看<程序员修炼之道>,其中谈到了最好精通一种编辑器,我觉得说的很有道理,于是重新下了最新版的sublime3,一步步 ...

  10. 分布式任务调度系统xxl-job源码探究(二、服务中心)

    接下来看下服务端代码 服务端源码 服务端通过管理quartz定时任务组件,分发任务 先从入口看起,由web.xml进入,可以看出,自己编写的代码从applicationcontext-xxl-job- ...