В чем все эта незамедлительная, зарезервированная память в моем процессе?

StackOverflow https://stackoverflow.com/questions/4503276

Вопрос

Я использую VMMAP из Sysinternals, чтобы посмотреть на память, выделенную моим процессом Win32 C ++ на WinXP, и я вижу кучу ассигнования, где части выделенной памяти зарезервированы, но не преданы. Насколько я могу судить, из моего чтения и тестирования все общие распределители памяти (например, Malloc, New, Localalloc, Globalalloc), используемые в программе C ++, всегда выделяют полностью совершенные блоки памяти. Кучи являются распространенным примером кода, который оставляет память, но не совершает ее до тех пор, пока это не нужно. Я подозреваю, что некоторые из этих блоков - это куча Windows/CRT, но, похоже, есть больше блоков, чем я ожидал бы от кучи. Я вижу в порядке 30 из этих блоков в своем процессе, размером от 64 до 8 МБ, и я знаю, что мой код никогда не намеренно называет Virtualalloc для распределения зарезервированной, незамеченной памяти.

Вот несколько примеров из VMMAP: http://www.flickr.com/photos/95123032@n00/5280550393/

Что еще будет выделить такие блоки памяти, где большая часть ее зарезервирована, но не предана? Имеет ли смысл, что у моего процесса есть 30 кучей? Спасибо.

Это было полезно?

Решение

Я понял это - это КЛТ -куча, которая выделяется призывом к malloc. Анкет Если вы выделяете большую часть памяти (например, 2 МБ), используя malloc, он выделяет один совершенный блок памяти. Но если вы выделяете меньшие куски (скажем, 177 КБ), то это зарезервирует кусок памяти 1 МБ, но займет только то, о чем вы просили (например, 184 КБ для моего запроса 177 КБ).

Когда вы освобождаете этот маленький кусок, этот больший кусок 1 МБ не возвращается в ОС. Все, кроме 4K, невозможно, но полный 1 МБ все еще зарезервирован. Если вы позвоните malloc Опять же, он попытается использовать этот кусок 1 МБ, чтобы удовлетворить ваш запрос. Если он не может удовлетворить ваш запрос с памятью, которая уже зарезервирована, он распределит новый кусок памяти, которая в два раза превышает предыдущее распределение (в моем случае он перешел от 1 МБ до 2 МБ). Я не уверен, продолжается ли этот шаблон удвоения или нет.

Чтобы вернуть свою освобожденную память в ОС, вы можете позвонить _heapmin. Анкет Я бы подумал, что это сделает будущее большое распределение, скорее всего, достигнет успеха, но все это будет зависеть от фрагментации памяти, и, возможно, Хипмин уже будет вызвана, если распределение не удается (?), Я не уверен. Также будет удар по производительности, так как Хипмин выпустит память (время), а затем Маллоку нужно будет переопределить ее из ОС, когда это снова необходимо. Эта информация предназначена для Windows/32 XP, ваш пробег может варьироваться.

Обновление: в моем тестировании Хипмин абсолютно ничего не сделал. И куча Malloc используется только для блоков, которые меньше 512 КБ. Даже если в куче Malloc есть MBS смежного свободного пространства, он не будет использовать его для запросов более 512 КБ. В моем случае это освобожденное, неиспользованное, но зарезервированное Malloc Memory Curge Coupe Up огромные части моего процесса 2 ГБ. А так как Хипмин не возвращает память в ОС, я не нашел никакого решения этой проблемы, кроме перезапуска моего процесса или написания собственного менеджера памяти.

Другие советы

Могут ли они быть DLL, загруженными в ваш процесс? DLL (и исполняемый файл) - это память, отображаемая в адресное пространство процесса. Я считаю, что это изначально просто оставляет пространство. Пространство поддерживается самими файлами (по крайней мере изначально), а не Pagefile.

Только код, который на самом деле затронут, затрагивается. Если я правильно понимаю терминологию, то это тогда, когда он совершается.

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

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

Если требуется больше, чем преданное количество памяти, будет возможно получить больше системной памяти.

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top