【发布时间】:2016-10-20 16:47:51
【问题描述】:
我们有一个运行在 5 个(服务器)节点(16 个内核,每个 128 GB 内存)上的应用程序,在每台机器上加载近 70 GB 数据。该应用程序是分布式的并为并发客户端提供服务,因此,有很多套接字使用。同样,对于多线程之间的同步,也有一些同步技术正在使用,主要是使用System.Threading.Monitor。
现在的问题是,当应用程序正在运行并且数据在这些服务器节点之间以及客户端和服务器之间传输时,即使还有 40+% 的内存可用,一台或两台服务器机器开始接收OutOfMemoryException。我们有一种感觉,这个异常来自非托管代码。虽然,我们没有直接进行任何非托管调用,但我们已经看到 OOM 异常堆栈跟踪中的最后一次调用始终是内部调用非托管代码的框架调用。
以下是几个例子。
Exception of type 'System.OutOfMemoryException' was thrown.
at System.Threading.Monitor.ObjPulseAll(Object obj)
....
Exception of type 'System.OutOfMemoryException' was thrown.
at System.Threading.Monitor.ObjWait(Boolean exitContext, Int32 millisecondsTimeout, Object obj)
at System.Threading.Monitor.Wait(Object obj, TimeSpan timeout)
....
我们对导致此问题的原因一无所知。我们已经在这些机器上多次诱导 GC,但这似乎也没有帮助。
任何帮助将不胜感激..
编辑:
以下是更多细节;
- 应用程序正在 x64 进程中运行。
- Windows Server 2012 R2
- .NET Framework 4.5
- 已启用服务器 GC
-
AllowLargeObject标志已设置。
EDIT2:请注意,这不是内存泄漏。 70 GB 进程大小在此处有效。
【问题讨论】:
-
您使用的是什么位操作系统?根据操作系统是否为 32/64 位,每个进程都有限制。
-
如果您尝试超过大多数对象的 2GB 限制,托管代码仍可能引发 OOM 异常
-
您是如何确定 LOH 的大小的?有多少个LOH?如果多个,每个 LOH 组合或每个单独 LOH 的大小是 10GB?另外,页面文件是启用还是禁用?页面文件有多大?操作系统显示的可用内存是多少?
-
您是否使用过任务管理器或进程资源管理器来找出正在使用的句柄、GDI 对象和用户对象的数量?
标签: c# .net out-of-memory clr