由于我在这方面学习了很多相关的知识,我将写下我根据自己的经验和答案中提供的建议所总结出来的技巧-
1) 使用内存分析器(从CLR Profiler开始尝试),找出消耗最大内存的例程并进行微调,如重复使用大型数组,尽量减少对象的引用。
2) 如果可能,分配小对象(对于.NET 2.0而言,小于85k),如果可以使用内存池,则避免垃圾回收器产生高CPU使用率。
3) 如果增加对象的引用,则需要相同次数地取消引用它们。这样做会让你放心,代码也可能更好地工作。
4) 如果什么都不管用,你仍然毫无头绪,那么请使用排除法(注释/跳过代码)找出消耗最多内存的是什么。
在代码内部使用内存性能计数器也可能有所帮助。
希望这些能够帮到你!
[原始问题]
嗨!
我正在使用C#编程,我的问题是内存不足异常。
我在这里读了一篇关于LOH的优秀文章 -> http://www.simple-talk.com/dotnet/.net-framework/the-dangers-of-the-large-object-heap/ 太棒了!
还有这篇文章: http://dotnetdebug.net/2005/06/30/perfmon-your-debugging-buddy/ 我的问题: 我正在面对企业级桌面应用程序的内存不足问题。我尝试阅读和理解有关内存分析和性能计数器的内容(也尝试过WinDBG!-稍微了解了一点),但仍然对基本知识毫无头绪。
我尝试使用CLR分析器来分析内存使用情况。它在以下方面很有帮助:
1) 显示哪些代码分配了大块内存
2) 哪种数据类型使用了最多的内存
但是,CLR Profiler和性能计数器(因为它们共享相同的数据)都无法解释:
1) 在每次运行应用程序后收集的数字 - 如何确定是否有任何改进???
2) 如何比较每次运行后的性能数据 - 特定计数器的较低/较高数字是好还是坏?
我需要的: 我正在寻找以下几个方面的技巧:
如何释放(是的,没错)托管数据类型对象(例如数组、大字符串),但不通过调用GC.Collect来实现,如果可能的话。我不得不处理每隔一段时间长度为500KB的字节数组(无法避免大小:-()。
如果发生碎片,如何压缩内存——因为似乎.NET GC并没有真正有效地做到这一点,导致OOM。
此外,LOH的85KB限制是指对象的大小还是数组的总大小?对我来说不是很清楚。
哪些内存计数器可以告诉我们代码更改是否真正减少了OOM的机会?
我已经知道的提示
将托管对象设置为null——标记它们为垃圾——以便垃圾收集器可以收集它们。这很奇怪——在将string[]对象设置为null后,所有堆中的字节数飙升了!
避免创建大于85KB的对象/数组——这不在我的控制范围内。因此,可能会有很多LOH。
3.
内存泄漏指标:
所有堆中的字节数增加 第2代堆大小增加 GC句柄数增加 固定对象数增加 总提交字节数增加 总保留字节数增加 大对象堆增加
我的情况:
- 我有一台4GB、32位机器,上面安装了Wink 2K3服务器SP2。
- 我知道一个应用程序可以使用<=2GB的物理RAM。
- 在这种情况下,增加虚拟内存(页面文件)大小没有效果。
由于是OOM问题,我只关注与内存相关的计数器。
请给予建议!我真的需要一些帮助,因为缺乏好的文档而陷入困境!