.NET 内存耗尽故障排除

4
阅读了几篇关于.NET技术中内存的启发性文章之后,我认为内存不足并非指物理内存597499。我以为我明白了为什么C#应用程序会抛出内存不足异常——直到我开始在两个服务器上进行实验——两者都有2.5GB的内存,运行Windows Server 2003和相同的程序。两者之间唯一显著的区别是一个硬盘存储空间只剩下7%,而另一个超过50%。存储空间只剩下7%的服务器持续抛出内存不足异常,而另一个则一直表现良好。我的应用程序是一个C# Web应用程序,处理数百MB的字符串对象。既然内存不足的最可能原因是连续虚拟地址空间不足,那么为什么会出现这种差异呢?

你正在进行哪种字符串操作?在内存方面,连接操作是昂贵的。也许重构(https://dev59.com/Pk3Sa4cB1Zd3GeqPzOg9#2871636)可以帮助解决问题。 - Dirk Vollmar
我正在使用XMLWriter包装在StringWriter中构建一个XML字符串。 - bushman
6个回答

8
我所能想到的是您正在耗尽虚拟内存。听起来像是需要在应用程序上运行内存分析器。
我过去在类似情况下使用Red Gate分析器。您可能会惊讶于您的字符串实际上使用了多少内存。

我实际上使用了Red Gate -- 在一个快照中显示了600MB+的内存消耗 -- 吓人,我知道 -- 但这是我必须面对的 :/ - bushman
1
那600MB中有多少实际数据?也许是时候寻找更好的数据结构或更好的处理方式了。如果您正在使用字符串对象进行任何字符串操作,请查看替代方案 - StringBuilder是一个不错的选择。并且查看您的GC统计信息,以查看它是否能够跟上,或者是否存在任何泄漏问题。 - chris

3

每台机器的页面文件碎片情况是否不同?高度碎片化可能会减缓分页操作,从而加剧内存问题。如果页面文件严重碎片化,请整理它,例如将服务器下线,将页面文件大小设置为零,对驱动器进行碎片整理,重新创建页面文件。

如果没有更多关于字符串处理的详细信息,很难给出任何具体的建议来解决性能问题。


我没有意识到分页文件存储在磁盘上。但是您的建议非常有道理。我会在谷歌上搜索如何执行您的建议,例如如何将分页文件设置为零等等。 谢谢。 - bushman
Sysinternal的PageDefrag可以解决页面碎片问题。尝试使用工作站或并发垃圾回收,看看问题是否会更少出现,这也值得一试。 - R Ubben

3
为什么会出现这种差异,因为内存不足的最可能原因是虚拟地址空间不连续?
由于硬盘只有7%的可用空间,您的服务器可能已经没有足够的空间将内存从您的进程或其他进程中分页出来,因此必须将所有内容保存在RAM中,因此您无法像50%可用空间的服务器那样频繁地分配额外的内存。
你们提出了什么解决方案?
既然您已经运行了分析器并看到至少使用了600MB+的字符串数据,那么您需要开始解决这个问题。
显然的答案是不要将所有数据都保存在内存中。如果您正在处理大型数据集,则应该逐步加载、处理,然后丢弃该部分并加载下一部分,而不是一开始就全部加载。
如果是需要提供的数据,请考虑缓存策略,例如LRU(最近最少使用)并仅保留最热门的数据在内存中,但将其余数据保留在磁盘上。
您甚至可以将字符串数据转移到数据库(内存或基于磁盘),并让它处理缓存管理。
我过去曾经使用过一个略微偏离常规的解决方案,就是在内存中压缩字符串数据,然后在需要时再进行解压缩,使用SharpZipLib。令人惊讶的是,它并不那么慢。

0

我认为你最好使用内存分析器。我曾经使用过.Net Memory Profiler 3.5并且成功地诊断了问题,我的问题是未释放的正则表达式语句。他们有演示教程,如果你不熟悉的话可以跟着步骤走。

至于你的问题,任何对字符串的单个引用,例如嵌套数组,都会阻止字符串被释放。如果不了解你的架构,很难做出具体的建议。我建议在扩展内存之前尝试优化你的应用程序。否则,这将在以后给你带来麻烦。


0

OutOfMemoryException 更可能表示页面文件的碎片化 - 而不是你的 RAM 或磁盘空间不足。

通常(错误地)认为页面文件用作交换磁盘 - 即将 RAM 溢出写入页面文件。 所有 分配的内存都存储在页面文件中,只有正在大量使用的数据才会被复制到 RAM 中。

除了尝试减少应用程序的内存占用之外,没有简单的代码修复此问题的方法。但如果你真的变得绝望,可以尝试 PageDefrag,这是 SysInternals 最初开发的免费应用程序。


这句关于“所有分配的内存都存储在页面文件中,只有正在密集使用的数据才会被复制到RAM” 的说法对我来说完全是错误的。你可以运行一个没有页面文件的服务器——仅凭这个事实就足以证明该说法是错误的。此外,该说法还违背了基本的硬件设计原则。 - Slaggg
@Slaggg:http://blogs.msdn.com/b/ericlippert/archive/2009/06/08/out-of-memory-does-not-refer-to-physical-memory.aspx - Phil Gan

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接