.NET中的托管堆就不会出现内存泄漏么?
2010-06-22 02:05
169 查看
答案是:即使在拥有GC的托管堆上,也有可能发生内存泄漏!
根据普遍意义上的内存泄漏定义,大多数的.NET内存对象在不再被使用后都会有短暂的一段时间的内存泄漏,因为要等待下一个GC时才有可能会被释放。但这种情况并不会对系统造成大的危害。
真正影响系统的严重内存泄漏情况如:
1:大对象的分配。
根据CLR的设计,.NET中的大对象将分配在托管堆内的一个特殊的区域,在回收大对象的时候,并不会像变通区域回收完成时要做内存碎片整理,这是因为这个区域都是大对象,对大对象的移动成本太大了。因此如果本来有三个连续的大对象,现在中间这个要释放掉了,然后新分配进来一个稍小点的大对象,这样势必在中间产生小的内存碎片,这个部分又无法利用。就造成了内存泄漏,并且除非碎片相邻的大对象被释放掉外,没法解决。 因此在编程时要注意大对象的操作,尽量减少大对象的分配次数。
2:避免根引用对象的分配
所谓的根引用对象就是那些GC不会去释放的对象引用。比如类的公共静态变量。 GC会视该变量对象在整个程序生命周期中都有效。因此就不会释放它。当它本身比较大,或者它内部又想用了其它很多对象时,这一连串的对象都无法在整个生命周期中得到释放。造成了较大的内存泄漏,应该时时注意这种风险的发生。
3:不合理的Finalize() 方法定义。
这个以后再进一步学习。
参考书籍:《.NET程序员面试指南》
参考网文: 发现并防止托管代码中出现内存泄漏
根据普遍意义上的内存泄漏定义,大多数的.NET内存对象在不再被使用后都会有短暂的一段时间的内存泄漏,因为要等待下一个GC时才有可能会被释放。但这种情况并不会对系统造成大的危害。
真正影响系统的严重内存泄漏情况如:
1:大对象的分配。
根据CLR的设计,.NET中的大对象将分配在托管堆内的一个特殊的区域,在回收大对象的时候,并不会像变通区域回收完成时要做内存碎片整理,这是因为这个区域都是大对象,对大对象的移动成本太大了。因此如果本来有三个连续的大对象,现在中间这个要释放掉了,然后新分配进来一个稍小点的大对象,这样势必在中间产生小的内存碎片,这个部分又无法利用。就造成了内存泄漏,并且除非碎片相邻的大对象被释放掉外,没法解决。 因此在编程时要注意大对象的操作,尽量减少大对象的分配次数。
2:避免根引用对象的分配
所谓的根引用对象就是那些GC不会去释放的对象引用。比如类的公共静态变量。 GC会视该变量对象在整个程序生命周期中都有效。因此就不会释放它。当它本身比较大,或者它内部又想用了其它很多对象时,这一连串的对象都无法在整个生命周期中得到释放。造成了较大的内存泄漏,应该时时注意这种风险的发生。
3:不合理的Finalize() 方法定义。
这个以后再进一步学习。
参考书籍:《.NET程序员面试指南》
参考网文: 发现并防止托管代码中出现内存泄漏
相关文章推荐
- .NET的托管堆中是否可能出现内存泄漏现象
- 发现并防止托管代码中出现内存泄漏,C# 内存泄漏,.net 内存泄漏
- 发现并防止托管代码中出现内存泄漏
- 发现并防止托管代码中出现内存泄漏
- .net调试程序时出现不会实现接口成员时解决办法
- 调试内存泄漏的应用程序 发现并防止托管代码中出现内存泄漏
- 发现并防止托管代码中出现内存泄漏
- .NET托管内存类应用的内存泄漏分析和诊断(转)
- .NET 1.1移植到.NET 2.0出现的一些小问题的解决
- .net 托管代码与非托管代码
- SharePoint 2010 .Net托管客户端模型简单示例
- .net系统回调java服务器json传参出现不可见字符
- .net连接Sql时出现"已成功与服务器建立连接,但是在登录过程中发生错误。 (provider: TCP 提供程序, error: 0 - 指定的网络名不再可用。) "
- .net导出Excel出现乱码问题
- 这个世界太疯狂了,不会调试,"错误: 托管 E 4000 E 不理解表达式的语法"
- db4o发布7.2,出现.NET 3.5版本,支持LINQ
- 用oralce连接.net客户端出现问题:“数据连接不成功,请检查该数据库是否已启动尝试加载oracle客户端时引发BadImageFormatException.如果在安装32位Oracle客户端组件的情况下以64位模式运行,”的解决办法
- 关于.Net 编程中出现的对方法不能转到定义的解决办法
- .Net 中访问Oracle 数据表,出现OCI-22053: overflow error
- .net项目中出现“无法直接启动带有类库输出类型的项目”的解决