Устранение неполадок ERROR_NOT_ENOUGH_MEMORY - PullRequest
5 голосов
/ 21 сентября 2009

Наше приложение не работает на компьютере конкретного пользователя с ERROR_NOT_ENOUGH_MEMORY («Недостаточно памяти для обработки этой команды»).

Ошибка, по-видимому, возникает где-то глубоко в рамках платформы Delphi VCL, которую мы используем, поэтому я не уверен, какая функция Windows API ответственна.

Является ли проблема с памятью? Вызов GlobalMemoryStatus дает следующую информацию:

  • dwTotalPhys - 1063150000 (~ 1 ГБ)
  • dwAvailPhys - 26735000 (~ 27 МБ)
  • dwAvailPage - 1489000000 (~ 1,4 ГБ)

Мне кажется странным, что Windows позволяла бы настолько уменьшать доступную физическую память, когда в файле подкачки доступно так много места, но я не знаю достаточно об управлении виртуальной памятью Windows, чтобы знать, нормально ли это или не. Это так?

Если не память, то какой ресурс ограничивается? Из того, что я читал в Интернете, ERROR_NOT_ENOUGH_MEMORY может быть результатом того, что приложение нарушает любое из нескольких ограничений (объекты GDI, объекты USER, дескрипторы и т. д.) и не обязательно память. Существует ли исчерпывающий список ограничений, которые применяются Windows? Есть ли какой-нибудь способ узнать, какой лимит был достигнут? Я попробовал Google, но не смог найти систематического обзора.

Ответы [ 4 ]

4 голосов
/ 21 сентября 2009

Проверьте все возможности.

GDI-проблемы можно отслеживать с помощью бесплатной утилиты GDIView . Это единственный файл, который пользователи могут запустить без установщика.

Кроме того, установите ProcessExplorer на соответствующую машину.

Если у вас нет доступа к аппарату, попросите пользователя сделать скриншоты состояния, отслеживаемого приложениями. Очень похоже, это даст вам подсказку.

3 голосов
/ 10 мая 2010

В этом случае виновником было CreateCompatibleBitmap . Очевидно, Windows может применять довольно строгие системные ограничения на объем памяти, доступной для зависящих от устройства растровых изображений (см., Например, это обсуждение списка рассылки ), даже если в вашей системе в противном случае имеется много памяти и много ресурсов GDI. (Эти общесистемные ограничения, очевидно, обусловлены тем, что Windows может выделять зависящие от устройства растровые изображения в памяти видеокарты.)

Решение состоит в том, чтобы просто использовать независимые от устройства растровые изображения (DIB) вместо этого (хотя они могут не обеспечивать столь же хорошую производительность). В этой статье базы знаний описывается, как выбрать оптимальный формат DIB для устройства.

Другие кандидаты на ограничение ресурсов (из ответов других и моего собственного исследования):

  • Ресурсы GDI (из этого ответа) - легко проверяются с помощью GDIView
  • Фрагментация виртуальной памяти (из этого ответа)
  • Настольная куча - см. здесь или здесь
3 голосов
/ 21 сентября 2009

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

0 голосов
/ 08 марта 2013

Мой ответ может быть немного запоздалым, но, исходя из моего позднего опыта с той же проблемой, я делаю все тесты, иду за шагом, создаю DC, освобождаю его, используя DIBSection вместо CompatibleBitmap, используя утечку GDI / инструменты памяти и т. Д.

В конце концов (LOL) я обнаружил, что:

Я переключал приоритет этих двух вызовов, затем вся проблема была исправлена.

DeleteDC(hdc);       //do it first (always before deleting objects)
DeleteObject(obj);
...