即使有30 GB的内存可用,仍会出现内存不足异常

6
我有一个(x64)程序,它消耗大量内存。我在win server 2008 R2 SP1上运行它,使用了48 GB RAM(64 bit).net frame work 4.5
我还在app.config中设置了gcAllowVeryLargeObjects = true
当我运行程序时,它会消耗18 GB的内存,然后就会出现异常。
EXCEPTION: System.OutOfMemoryException: Insufficient memory to continue the execution of the program.

   at System.Text.StringBuilder.ExpandByABlock(Int32 minBlockCharCount)
   at System.Text.StringBuilder.Append(Char* value, Int32 valueCount)
   at System.Text.StringBuilder.Append(String value)
   at System.Xml.XmlTextEncoder.Write(String text)
   at System.Xml.XmlTextWriter.WriteWhitespace(String ws)
   at System.Xml.XmlElement.WriteElementTo(XmlWriter writer, XmlElement e)
   at System.Xml.XmlNode.get_OuterXml()
   at System.Security.Cryptography.Xml.Utils.PreProcessElementInput(XmlElement e
   lem, XmlResolver xmlResolver, String baseUri)
   at System.Security.Cryptography.Xml.Reference.CalculateHashValue(XmlDocument
   document, CanonicalXmlNodeList refList)
   at System.Security.Cryptography.Xml.SignedXml.BuildDigestedReferences()
   at System.Security.Cryptography.Xml.SignedXml.ComputeSignature()

尽管我们还剩下30GB的内存,但它仍然提示“内存不足”的错误信息。这是.NET应用程序的限制还是服务器的问题?


1
可能是分段问题吗?如果强制进行垃圾回收,错误是否会发生?或者也许是这个:https://dev59.com/kmsz5IYBdhLWcg3w9s2r#7537821 - Giedrius
通常框架抛出的OOM异常没有堆栈信息。请查看 StringBuilder.ExpandByABlock 的源代码 - 它在某些情况下故意抛出OOM异常。 - mikalai
2个回答

7
您遇到了 StringBuilder 类的内部限制,它无法生成超过 int.MaxValue 个字符的字符串。这在 .NET 中是一个相当严格的限制,gcAllowVeryLargeObjects 可以帮助但不能解决它。核心问题是 int 类型已经不足以索引字符串了。
您需要编写更智能的代码来解决这个问题。首先需要使用 StreamWriter 而不是 StringWriter。换句话说,将数据写入文件而不是内存中。
您仍然可以使用计算机上所有的 RAM,因为文件会首先被写入文件系统缓存。程序也不会变慢。

0

有一件事情讓我想到了,即使問題中沒有明確的證據。

請記住,在 BCL 中,List<T> 集合有內存限制,無論是 32 位還是 64 位。單個集合實例可以分配的最大內存量不超過 2GB

您可以查看您的類型使用情況,特別是對於 List<T>,是否發生了某些泄漏。

希望這能幫助到您。


1
gcAllowVeryLargeObjects:在64位平台上启用总大小大于2 GB的数组:http://msdn.microsoft.com/en-us/library/hh285054%28v=vs.110%29.aspx - Giedrius

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