思维的乐趣

Enjoy it
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

.NET中的托管堆就不会出现内存泄漏么?

Posted on 2010-06-22 02:05  szh114  阅读(754)  评论(0编辑  收藏  举报

答案是:即使在拥有GC的托管堆上,也有可能发生内存泄漏!

 

根据普遍意义上的内存泄漏定义,大多数的.NET内存对象在不再被使用后都会有短暂的一段时间的内存泄漏,因为要等待下一个GC时才有可能会被释放。但这种情况并不会对系统造成大的危害。

真正影响系统的严重内存泄漏情况如:

 

1:大对象的分配。

根据CLR的设计,.NET中的大对象将分配在托管堆内的一个特殊的区域,在回收大对象的时候,并不会像变通区域回收完成时要做内存碎片整理,这是因为这个区域都是大对象,对大对象的移动成本太大了。因此如果本来有三个连续的大对象,现在中间这个要释放掉了,然后新分配进来一个稍小点的大对象,这样势必在中间产生小的内存碎片,这个部分又无法利用。就造成了内存泄漏,并且除非碎片相邻的大对象被释放掉外,没法解决。   因此在编程时要注意大对象的操作,尽量减少大对象的分配次数。

 

2:避免根引用对象的分配

所谓的根引用对象就是那些GC不会去释放的对象引用。比如类的公共静态变量。 GC会视该变量对象在整个程序生命周期中都有效。因此就不会释放它。当它本身比较大,或者它内部又想用了其它很多对象时,这一连串的对象都无法在整个生命周期中得到释放。造成了较大的内存泄漏,应该时时注意这种风险的发生。

 

3:不合理的Finalize() 方法定义。

这个以后再进一步学习。

 

 

参考书籍:《.NET程序员面试指南》

参考网文: 发现并防止托管代码中出现内存泄漏