这应该是一个连续运行的,无人值守的控制台应用程序的问题:我看到来自System.OutOfMemoryException
的应用程序退出频繁出现在调用堆栈深处的各种方法中 - 通常System.String.ToCharArray()
,System.String.CtorCharArrayStartLength()
或System.Xml.XmlTextReaderImpl.InitTextReaderInput()
,但有时会在System.String.Concat()
电话的筹码中MongoCollection.Save()
来电,以及其他不太可能的地方。
对于它的价值,我们使用并行任务,但这实际上是服务器上运行的唯一应用程序,并且应用程序的总线程数永远不会超过60.在某些情况下我知道抛出一些其他异常的原因,但OutOfMemoryException在这些上下文中没有任何意义,并且它会产生问题:
所以我知道上面提到的解决方法,但我真正喜欢的是一些解释 - 理想情况下是一个基于代码的处理程序 - 用于意外的OOM异常,以便我们可以使用适当的延续逻辑。有什么想法吗?
答案 0 :(得分:2)
在使用3GB内存时获取该异常表明您运行的是32位应用程序。将其构建为64位应用程序,它将能够使用尽可能多的内存(接近8GB)。
至于为什么它首先失败了......你使用的数据有多大?如果它不是很大,你是否寻找对数据的引用要比它们所需的时间长得多(即内存泄漏),从而阻止正确的GC?
答案 1 :(得分:2)
您需要对应用程序进行概要分析,但这些异常的最常见原因是过多的字符串创建。此外,过多的序列化可能会导致这种情况和过多的Xslt转换。
答案 2 :(得分:1)
你有很多大于或等于85000字节的对象吗?每个这样的对象都将转到大对象堆,即not compacted。即与小对象堆不同,GC将不移动对象以填充内存空洞,这可能导致碎片化,这对于长期应用程序来说是一个潜在的问题。
从.NET 4开始,情况仍然如此,但似乎是some improvements in .NET 4.5。
快速而肮脏的解决方法是确保应用程序可以通过将其构建为“x64”或“任何CPU”来使用所有可用内存,但真正的解决方案是尽量减少大型重复分配/释放周期对象(即如果可能的话,使用对象池或完全避免大对象)。
您可能还想查看this。