Выделение не освобождает память в приложении Windows / C ++ - PullRequest
3 голосов
/ 15 декабря 2008

Мое приложение Windows / C ++ выделяет ~ 1 ГБ данных в памяти с оператором new и обрабатывает эти данные. После обработки данные удаляются.

Я заметил, что если я снова запускаю обработку, не выходя из приложения, второй вызов оператору new для выделения ~ 1 ГБ данных завершается неудачей.

Я ожидаю, что Windows вернет память обратно. Можно ли лучше управлять этим с помощью некоторых других вызовов Win32 и т. Д.?

Ответы [ 5 ]

6 голосов
/ 15 декабря 2008

Не думаю, что это проблема Windows. Проверьте, правильно ли вы использовали delete или []. Возможно, это поможет, если вы разместите код, который выделяет / освобождает память.

5 голосов
/ 15 декабря 2008

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

Библиотека времени выполнения Microsoft C пытается вернуть память обратно операционной системе, вызывая _heapmin_region вызов _heap_free_region или _free_partial_region, который вызывает VirtualFree для передачи данных в операционную систему. Однако если целые страницы в соответствующем регионе не пусты, они не будут освобождены. Распространенной причиной этого является кэширование бухгалтерской информации и хранилища контейнеров C ++.

3 голосов
/ 15 декабря 2008

Это может происходить из-за фрагментации памяти (в действительности, фрагментации адресного пространства), когда различные факторы внесли свой вклад в адресное пространство вашей программы, не имея доступной непрерывной дыры 1 ГБ. На самом деле, я подозреваю ошибку в вашем управлении памятью (извините) - вы запускали свой код с помощью обнаружения утечек?

1 голос
/ 11 апреля 2010

Эта проблема почти наверняка фрагментации памяти. В 32-битной Windows самый большой непрерывный регион, который вы можете выделить, составляет около 1,1 ГБ (поскольку различные библиотеки DLL в вашем EXE-файле препятствуют расширению непрерывного диапазона). Если после освобождения выделения памяти (или загрузки DLL, или файла отображения памяти) окажется в середине вашей предыдущей области 1 ГБ, то больше не будет области 1 ГБ, доступной для вашего следующего вызова new для выделения 1 ГБ. Таким образом, он потерпит неудачу.

Вы можете визуализировать этот процесс, используя VM Validator .

1 голос
/ 15 декабря 2008

Поскольку вы используете очень большие блоки памяти, вам следует рассмотреть возможность использования VirtualAlloc () и VirtualFree () , поскольку они позволяют вам выделять и освобождать страницы напрямую, без накладных расходов (по памяти и времени) взаимодействия с менеджером кучи.

Поскольку вы используете C ++, стоит отметить, что вы можете создавать объекты C ++ в памяти, которую вы выделяете таким образом, используя размещение нового .

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