2013-09-30 60 views
4

我有一个程序(x64)会消耗大量内存。 我在win server 2008 R2 SP1上运行它48 GB RAM(64 bit),.net frame work 4.5即使30 GB内存空闲,内存异常也不充足

我也曾在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() 

它给人以“内存不足”,然而,我们仍然有30 GB的内存免费。 是.net应用程序或服务器给我这个错误的限制。

+1

它可能是碎片问题,如果您强制GC发生错误?或者可能是这样的:http://stackoverflow.com/a/7537821/212121 – Giedrius

+0

通常框架抛出的OOM没有堆栈。查看'StringBuilder.ExpandByABlock'源代码 - 它在某些情况下故意抛出OOM。 – mikalai

回答

0

即使在这个问题上没有明确的证据,我仍然会想到一件事。

请记住,在BCLList<T>集合的内存限制,无论是32位还是64位。最大内存量单个集合实例可以在两种体系结构上分配不多于2GB

您可以对您的使用类型看,expecially为List<T>,如果有一些泄漏发生。

希望这会有所帮助。

+1

gcAllowVeryLargeObjects:在64位平台上,启用总大小大于2千兆字节(GB)的数组:http://msdn.microsoft.com/en-us/library/hh285054%28v=vs.110%29。 ASPX – Giedrius

3

您正在运行到StringBuilder类的内部限制,它无法产生具有超过int.MaxValue字符的字符串。这个限制在.NET中是非常严格的,gcAllowVeryLargeObjects可以帮助但不能解决它。核心问题是int类型不够大,无法索引字符串。

你必须编写更聪明的代码来解决这个问题。这需要使用StreamWriter而不是StringWriter开始。换句话说,写入文件而不是内存。

你仍然可以使用所有的机器上的RAM你有,文件首先写入到文件系统缓存。你的程序不会变慢。