关于内存回收,内存释放,垃圾回收的几个概念

poiuy1363 2009-05-23 10:03:43
大概知道就是那么个道理,但不是很明确各自的特点。
知道的朋友说说内存回收,内存释放,垃圾回收及其相关的几个概念,
他们到底有什么区别和联系,以及编程中应该注意的问题。
让大家一起学习学习
...全文
421 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
poiuy1363 2009-05-25
  • 打赏
  • 举报
回复
熟悉底层的朋友来聊聊。。。
yangjiang113 2009-05-23
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 jueyingfd 的回复:]
内存回收
以前在使用new来开辟的内存区域后,就只用delete来进行内存回收,其实这还不完全。仅仅将其删去,但指向这块内存区域的指针还存在(成为野指针了,书面上称为悬挂指针-dangling pointer),当在后面不小心再次删去时就会报错了。所以在delete后,还要将其赋值为NULL。 而且在删除指针前应该判断其是否为空,这样就会避免多次删除一个指针而报错。如下例:
char …
[/Quote]
waittime 2009-05-23
  • 打赏
  • 举报
回复
顶!
jueyingfd 2009-05-23
  • 打赏
  • 举报
回复
内存回收
以前在使用new来开辟的内存区域后,就只用delete来进行内存回收,其实这还不完全。仅仅将其删去,但指向这块内存区域的指针还存在(成为野指针了,书面上称为悬挂指针-dangling pointer),当在后面不小心再次删去时就会报错了。所以在delete后,还要将其赋值为NULL。 而且在删除指针前应该判断其是否为空,这样就会避免多次删除一个指针而报错。如下例:
char * pstrFilePath;
...
if(pstrFilePath != NULL)
{
delete pstrFilePath; //如果pstrFilePath为数组,则delete []pstrFilePath;
pstrFilePath = NULL;
}
而且野指针常常会导致系统出现内存泄漏,尤其是在一个涉及到大块内存调度和频繁读写内存的进程中。其实解决野指针还有一个好办法--使用引用计数器。引用计数器是一个对引用字符串在内存中的字符串数据的指针进行计数的整数。每当一个新指针指向这个字符串,计数器就加一,相反每释放一次就减一,当计数器为0时才真正进行内存释放。

垃圾回收
.NET Framework 的垃圾回收器管理应用程序的内存分配和释放。每次您使用 new 运算符创建对象时,运行库都从托管堆为该对象分配内存。只要托管堆中有地址空间可用,运行库就会继续为新对象分配空间。但是,内存不是无限大的。最终,垃圾回收器必须执行回收以释放一些内存。垃圾回收器优化引擎根据正在进行的分配情况确定执行回收的最佳时间。当垃圾回收器执行回收时,它检查托管堆中不再被应用程序使用的对象并执行必要的操作来回收它们占用的内存。
poiuy1363 2009-05-23
  • 打赏
  • 举报
回复
请用自己的话解释各个概念,这样有助于大家交流,谢谢
zealot1021 2009-05-23
  • 打赏
  • 举报
回复
学习,顶起
evaa006 2009-05-23
  • 打赏
  • 举报
回复
.net内存回收与Dispose﹐Close﹐Finalize方法

一. net的对象使用一般分为三种情况﹕

1.创建对象
2.使用对象
3.释放对象

二.创建对象
1.创建对象实际分为两个步骤﹕变量类型宣告和初始化对象
2.变量类型宣告(declare),如﹕FileStreamfs
这行代码会在当前的变量作用域空间(栈或堆)里建立一个叫做fs的变量﹐至少四个字节吧(因为要存一个对象的地址)
3.初始化对象
对象在使用(调用其方法或属性)前﹐必须进行初始化。
如﹕
fs=newFileStream(@"C: est.txt",FileMode.OpenOrCreate);
这行代码会分成3个步骤﹕
a.在托管堆中分配一块内存﹐其大小等于FileStream中所有字段(当然不包括静态的)的内存总和加上MS认为需要的其它东东。
b.初始化对象的字段(值类型的把其位全部初始化成0,对象初始化为null﹐当然string是一个例外﹐它被初始化成空字符串)
c.调用FileStream相应的构造器﹐这里会初始化一个非托管资源(文件)的私有字段。

三.使用对象
使用对象就没什么讲的﹐就是调用对象的方法(或属性等)来完成某个功能当然为了释放对象而调用的方法其范畴应不属于此类中(现在提到的Finalize等)

四.释放对象
1.释放对象也就是说这个对象我已经不需要了﹐现在我要把其释放﹐以便把其在堆上所占用的内存空间给收回来(当然变量名的内存空间就不需要管了﹐因为它会随其作用域自动消失)

2. .net自动进行内存管理﹐也就是说当它判断一个对象没有用了(当然有自己的算法)﹐它就会将其内存给自动收回来﹐但是其收回的时间一般不确定(当.net认为内存紧张时﹐它就会开始)

BTW:其实我们就是想自己收回对象的内存也不可能﹐因为MS没有提供途径(GC.Collect也是启动.net的内存收集功能)

五.第一个结论
在net中使用对象很简单﹐创建对象之后直接使用就可以了﹐不用了也不要去管它﹐垃圾收集器会帮你把内存要回来的。

六.例外
当对象的成员引用了一个非托管资源时(不在托管堆上分配的内存或资源﹐像文件﹐数据库连接等等)﹐下面以一个例子来说明﹕
System.IO.FileStream类别﹐这是.net基本类库提供的一个非托管资源(文件)封装对象(用Reflector工具反编译mscorlib.dll可见其代码)

1.FileStream毫无疑问封装了一个非托管资源

观其源代码发现有这样一个私有成员﹕


privateSafeFileHandle_handle;
通过构造器调用的Init方法可以发现这个成员的初始化代码﹕


this._handle=Win32Native.SafeCreateFile(text2,num1,share,secAttrs,mode,num2,
Win32Native.NULL);
而后者实际上就是kernel32.dll中的CreateFile方法﹐它返回一个HANDLE(即非托管资源引用)


GC可以参考相关文章

62,046

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术交流专区
javascript云原生 企业社区
社区管理员
  • ASP.NET
  • .Net开发者社区
  • R小R
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

.NET 社区是一个围绕开源 .NET 的开放、热情、创新、包容的技术社区。社区致力于为广大 .NET 爱好者提供一个良好的知识共享、协同互助的 .NET 技术交流环境。我们尊重不同意见,支持健康理性的辩论和互动,反对歧视和攻击。

希望和大家一起共同营造一个活跃、友好的社区氛围。

试试用AI创作助手写篇文章吧