Когда вызывать SetProcessWorkingSetSize? (Убедить менеджера памяти освободить память)
В предыдущем посте ( Моя программа никогда не освобождает память обратно. Почему?) Я показываю, что FastMM может кэшировать (читать как удерживать для себя) довольно большие объемы памяти. Если ваше приложение только что загрузило большой набор данных в ОЗУ, после освобождения данных вы увидите, что впечатляющие объемы ОЗУ не возвращаются обратно в пул памяти.
Я оглянулся и кажется, что вызов API-функции SetProcessWorkingSetSize "сбросит" кеш на диск. Однако я не могу решить, когда вызывать эту функцию. Я хотел вызвать его в конце события OnClick на кнопке, выполняющей интенсивную работу с ОЗУ. Однако некоторые люди говорят, что это может вызвать AV.
Если кто-нибудь успешно использовал эту функцию, пожалуйста, сообщите мне (нам).
Большое спасибо.
Редактировать:
1. После освобождения набора данных программа по-прежнему занимает много оперативной памяти. После вызова SetProcessWorkingSetSize размер возвращается к нескольким МБ. Некоторые утверждают, что ничего не было выпущено обратно. Согласен. Но объем памяти в памяти теперь невелик, и он НЕ увеличивается после нормального использования программы (например, при выполнении обычной операции, которая не требует загрузки больших наборов данных). К сожалению, нет никакого способа продемонстрировать, что подкачанная память на диск когда-либо загружается обратно в память, но я думаю, что это не так. 2. Я уже продемонстрировал (надеюсь), что это не утечка памяти:
Моя программа никогда не освобождает память обратно. Зачем?
Как убедить менеджер памяти освободить неиспользуемую память
5 ответов
Задача решена:
Мне не нужно использовать SetProcessWorkingSetSize. FastMM в конечном итоге освободит ОЗУ.
Чтобы подтвердить, что это поведение генерируется FastMM (как предложено Барри Келли), я написал вторую программу, которая выделяла МНОГО ОЗУ. Как только в Windows кончилось ОЗУ, использование памяти моей программой вернулось к своему первоначальному значению.
Если SetProcessWorkingSetSize решит вашу проблему, то ваша проблема не в том, что FastMM удерживает память. Поскольку эта функция просто обрезает рабочий набор вашего приложения, записывая память в ОЗУ в файл подкачки. Ничто не выпущено обратно в Windows.
Фактически, вы только снова сделали доступ к памяти более медленным, поскольку теперь его нужно читать с диска. Этот метод имеет тот же эффект, что и сворачивание вашего приложения. Затем Windows предполагает, что вы не собираетесь снова использовать приложение в ближайшее время, а также записывает рабочий набор в ОЗУ в файл подкачки. Windows хорошо решает, когда записывать ОЗУ в файл подкачки, и старается хранить в ней максимально используемую память как можно дольше. Это уменьшит размер рабочего набора (запись в файл подкачки), когда останется мало ОЗУ. Я не стал бы возиться с этим, просто чтобы создать иллюзию того, что ваша программа использует меньше памяти, хотя на самом деле она использует столько же, сколько раньше, только теперь доступ к ней медленнее. Память, к которой снова осуществляется доступ, будет снова загружена в ОЗУ и снова увеличит размер рабочего набора. При меньшем объеме памяти размер рабочего набора уменьшается.
Так что нет, это не поможет вам заставить FastMM освободить память. Если ваша цель состоит в том, чтобы ваше приложение использовало меньше памяти, вы должны искать в другом месте. Ищите утечки, ищите фрагменты кучи, ищите оптимизацию, и если вы думаете, что FastMM удерживает вас от этого, вы должны попытаться найти факты, подтверждающие это. Если ваша цель состоит в том, чтобы размер рабочего набора был небольшим, вы можете попытаться сохранить доступ к своей памяти локально. Может быть, FastMM или другой менеджер памяти могут помочь вам в этом, но это совсем другая проблема по сравнению с использованием большого количества памяти. И, возможно, эта функция поможет вам решить проблему, с которой вы столкнулись, но я бы использовал ее с осторожностью и, конечно, не использовал бы ее просто для того, чтобы создать иллюзию того, что ваша программа использует мало памяти.
Я согласен с Lars Truijens на 100%, если вы этого не сделаете, вы можете проверить использование памяти FasttMM через вызовы FasttMM GetMemoryManagerState и GetMemoryManagerUsageSummary до и после вызова API SetProcessWorkingSetSize.
Вы уверены, что есть проблема? Рабочие наборы могут уменьшиться только тогда, когда действительно не хватает памяти.
Я использовал эту функцию только один раз, когда я реализовал TWebBrowser. Этот компонент занял у меня столько памяти, даже если я уничтожил экземпляр.