System.Runtime.InteropServices.COMException (0x80070008): недостаточно места для обработки этой команды - PullRequest
8 голосов
/ 12 марта 2010

Я пытаюсь диагностировать это исключение:

System.Runtime.InteropServices.COMException (0x80070008): Not enough storage is available to process this command. (Exception from HRESULT: 0x80070008)
at System.Runtime.Remoting.RemotingServices.AllocateUninitializedObject(RuntimeType objectType)
at System.Runtime.Remoting.RemotingServices.AllocateUninitializedObject(Type objectType)
at System.Runtime.Remoting.Activation.ActivationServices.CreateInstance(Type serverType)
at System.Runtime.Remoting.Activation.ActivationServices.IsCurrentContextOK(Type serverType, Object[] props, Boolean bNewObj)
at Oracle.DataAccess.Client.CThreadPool..ctor()
at Oracle.DataAccess.Client.OracleCommand.set_CommandTimeout(Int32 value)
...

Похоже, что ни один из нормальных типов «хранилищ» не достиг каких-либо ограничений. Приложение использует около 400 МБ памяти, 70 потоков, 2000 дескрипторов, а на жестком диске много свободных ГБ. На компьютере установлена ​​32-разрядная ОС Windows 2003 Enterprise Server с 16 ГБ ОЗУ, поэтому проблема с памятью не должна быть.

Приложение работает как служба Windows, поэтому объекты GDI не используются. Нехватка дескрипторов GDI является распространенной причиной этого исключения.

Все соединения с базой данных, команды и читатели упакованы с использованием блоков, поэтому они должны быть очищены правильно.

ОБНОВЛЕНИЕ: Уменьшение количества потоков, которые мы использовали с 12 до 4, похоже, решило проблему. Нам удалось работать без ошибок более 24 часов, прежде чем мы продержались от 4 до 8 часов. ОБНОВЛЕНИЕ2: Я так и не понял, из какого ресурса у нас заканчивается, но уменьшение количества потоков, похоже, решило проблему. Или, по крайней мере, скрыл это.

Ответы [ 3 ]

6 голосов
/ 12 марта 2010

Еще один фактор, который необходимо учитывать, - это фрагментация памяти.

Максимальное одиночное выделение, которое вы можете выполнить, равно наибольшему непрерывному блоку памяти, доступному для процесса. Это почти всегда меньше, чем общий объем памяти, доступной в процессе из-за фрагментации. То есть выделяются блоки памяти, расположенные между 2 свободными блоками памяти, «фрагментирующими» пространство.

Чем больше у вас фрагментации, тем меньше будет самый большой непрерывный блок памяти, который будет доступен. Я видел ситуации, когда было около 1 ГБ свободной памяти, но самый большой непрерывный блок был около 10 МБ.

Проверяли ли вы фрагментацию памяти в этом процессе?

2 голосов
/ 18 марта 2010

Вы устранили все очевидные источники этой ошибки для вашего процесса. Вероятно, это проблема операционной системы. Единственный ресурс, который всегда находится под давлением на сервере, - это пул памяти ядра. Это легко увидеть, TaskMgr.exe отображает его на вкладке «Производительность».

Это несколько соответствует вашему стеку вызовов, похоже, что поставщик Oracle создает потоки для пула потоков. Поток занимает мегабайт в вашем процессе и 24 КБ в пуле памяти ядра, используется в качестве стека, когда поток переключается в режим ядра.

Справочная информация доступна здесь .

0 голосов
/ 12 марта 2010

Похоже, что-то зацикливается и создает слишком много объектов в куче, поэтому вам не хватает памяти в куче. Ищите любые петли в вызывающем коде.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...