我们有一个应用程序运行在5个(服务器)节点上(每个节点有16个核心,128 GB内存),每台机器上加载近70 GB的数据。该应用程序是分布式的,可以为并发客户端提供服务,因此有很多套接字使用。同样,为了在多个线程之间进行同步,使用了一些同步技术,主要使用了System.Threading.Monitor
。
现在的问题是,当应用程序正在运行并且数据正在服务器节点和客户端之间传输时,其中一两台服务器机器开始收到OutOfMemoryException
异常,即使仍然有40%以上的内存可用。我们有一个感觉这个异常来自非托管代码。虽然我们没有直接调用任何非托管函数,但我们已经看到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
标志已设置。
编辑2:请注意,这不是内存泄漏。70GB的进程大小在这里是有效的。