网站导航免费论文 原创论文 论文搜索 原创论文 网学软件 学术大家 资料中心 会员中心 问题解答 原创论文 大学论文导航 设计下载 最新论文 下载排行 原创论文 论文源代码
返回网学首页
网学联系
最新论文 推荐专题 热门论文 素材专题
当前位置: 网学 > 编程文档 > ASP.net > 正文

我对IDisposable接口的理解

来源:http://myeducs.cn 联系QQ:点击这里给我发消息 作者: 用户投稿 来源: 网络 发布时间: 12/10/12
++中那样内存管理工作的复杂性。虽然不必手工管理内存,但如果要编写高效的代码,就仍需理解后台发生的事情。

一面运行没有错误,可总想知道这个dispose方法到底做了些什么.既然是释放资源,那么类被释放后应该就被销毁,它的引用应该是不存在的,于是本人的测试代码如下:

Code
try
{
if (_foo == null)
{
//对象调用Dispose()后应该运行到此外
Response.Write("资源已经释放啦!");

}
else
{
Response.Write(_foo.GetType().ToString());
//资源是否已经被释放 此时为true
bool isRelease4 = _foo.m_disposed;
bool isAdded2 = _foo.AddUser();

}

}
catch (Exception ex)
{
Response.Write("ERR");

}
本想应该会运行Response.Write("资源已经释放啦!"),可是结果相反,它的引用依然存在.这让我不解,后来得到园友jyk的指点,他让我试下,.net下实现了dispose方法的类,我就用Stream试了下,测试结果好下:

Code
Stream _s = this.FileUpload1.PostedFile.InputStream;
//客户端文件大小 为了判断对象是否被销毁
long orgLength = _s.Length;
_s.Dispose();
try
{
if (_s == null)
{
Response.Write("资源已经释放啦!");

}
else
{
Response.Write(_s.GetType().ToString());
//客户端文件大小 此处为释放资源后
//运行结果表明,此时的文件流的大小是0
//说明资源已经成功释放
long _length= _s.Length;

}

}
catch (Exception ex)
{
Response.Write("ERR");

}

运行结果我们可以非常清楚的看出,Stream资源已经被释放,因为两次访问Stream的大小,发现在dispose后的大小为零.这就好像是第一次初始化的结果.但Stream属于非托管资源,如果是托管资源呢?在Foo的测试代码中发现,释放前后的变量(m_disposed,调用Dispose前为false,调用后为true,而且还可以调用类的方法)发生了变化,并不是我想象当中的初始化.这是让我一直不解的地方.

后来在资料书上看,发现IDisposable接口是专门针对未托管资源而设计的.它在托管资源上没有特别大的帮助.最终的资源回收工作还得要GC.我们看下托管资源和非托管资源在内存上的分配情况.

/*非托管资源一般都是放在堆栈上,而托管资源都是存储在堆上.*/ 非常感谢 Angel Lucifer的指教,本人见笑了 特此删除:


值类型与引用类型在内存分配上的分别:

值类型存储在堆栈中,堆栈的工作原理就是先进后出.它在释放资源的顺序上与定义变量时分配内存的顺序相反.值变量一旦出了作用域就会从堆栈中删除对象.

引用类型则存储在堆中.,当new一个类时,此时就会为对象分配内存存入托管堆中,它可以在方法退出很长的时间后仍然可以使用.我以一句常用的实例类的语句来说明下.

classA a=new classA();

这句非常平常的语句其实可以分成两部分来看:

第一:classA a;声明一个classA的引用a,在堆栈上给这个引用分配存储空间.它只是个引用,并不是真正的对象.它包含存储对象的地址.
第二:a=new classA();分配堆上的内存,以存储真正的对象.然后修改a的值为新对象的内存地址.

当引用出了作用域后,就会从堆栈上删除引用,但引用对象的数据仍然存储在托管堆中,一直到程序停止,或者是GC删除.

所在这点就可以解释我上面写的Foo类在调用Dispose方法后,程序仍然可以访问对象的原因了.

/*我认为堆是否就有像asp.net中的缓存功能,它可以将对象缓存起来,对象只要创建一次就可以在一定的有限时间内存在.*/
非常感谢 Angel Lucifer的指教 特此更正如下:
这种情况完全是因为GC回收操作的不可预测性导致的。GC Heap上的对象生存期完全看GC是否要回收它而决定。此外,值类型完全没必要实现 IDisposable 接口。

总结:
如果你的类中没有用非托管资源,或者是非常大的实例(象 GIS 中的Geometry), 就没有太大的必要实现这个

网学推荐

免费论文

原创论文

设为首页 | 加入收藏 | 论文首页 | 论文专题 | 设计下载 | 网学软件 | 论文模板 | 论文资源 | 程序设计 | 关于网学 | 站内搜索 | 网学留言 | 友情链接 | 资料中心
版权所有 QQ:3710167 邮箱:3710167@qq.com 网学网 [Myeducs.cn] 您电脑的分辨率是 像素
Copyright 2008-2015 myeducs.Cn www.myeducs.Cn All Rights Reserved 湘ICP备09003080号