У нас есть приложение, работающее на 5 (серверных) узлах (16 ядер, 128 ГБ памяти каждый), которые загружают почти 70 ГБ данных на каждом компьютере. Это приложение распространяется и обслуживает одновременных клиентов, поэтому существует много использования сокетов. Аналогично, для синхронизации между несколькими потоками используется несколько методов синхронизации, в основном используя 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 на эти машины несколько раз, но это также не помогает.
Любая помощь будет оценена.
EDIT:
Ниже приведены некоторые подробности:
- Приложение работает в процессе x64.
- Windows Server 2012 R2
- .NET Framework 4.5
- Сервер GC включен
-
AllowLargeObject
установлен флаг.
EDIT2: Обратите внимание, что это не утечка памяти. Здесь доступен размер процесса 70 ГБ.