Когда вызывать SetProcessWorkingSetSize?(Убедить менеджера памяти освободить память) - PullRequest
2 голосов
/ 21 декабря 2010

В предыдущем посте ( Моя программа никогда не освобождает память назад. Почему? ) Я показываю, что FastMM может кэшировать (читать как удерживать для себя) довольно большие объемы памяти. Если ваше приложение только что загрузило большой набор данных в ОЗУ, после освобождения данных вы увидите, что впечатляющие объемы ОЗУ не возвращаются обратно в пул памяти.

Я оглянулся и кажется, что вызов функции API SetProcessWorkingSetSize "сбросит" кэш на диск. Однако я не могу решить, когда вызывать эту функцию. Я хотел вызвать его в конце события OnClick на кнопке, выполняющей интенсивную работу с ОЗУ. Однако некоторые люди говорят, что это может вызвать AV.

Если кто-нибудь успешно использовал эту функцию, пожалуйста, сообщите мне (нам).

Большое спасибо.


Edit:
1. После освобождения набора данных программа по-прежнему занимает много оперативной памяти. После вызова SetProcessWorkingSetSize размер возвращается к нескольким МБ. Некоторые утверждают, что ничего не было выпущено обратно. Согласен. Но объем памяти в памяти теперь невелик, и он НЕ увеличивается после нормального использования программы (например, при выполнении обычной операции, которая не требует загрузки больших наборов данных). К сожалению, нет никакого способа продемонстрировать, что подкачанная память на диск когда-либо загружается обратно в память, но я думаю, что это не так. 2. Я уже продемонстрировал (надеюсь), что это не утечка памяти:
Моя программа никогда не освобождает память обратно. Почему?
Как убедить менеджер памяти освободить неиспользуемую память

Ответы [ 5 ]

13 голосов
/ 21 декабря 2010

Если SetProcessWorkingSetSize решит вашу проблему, то ваша проблема не в том, что FastMM удерживает память. Так как эта функция просто обрежет рабочий набор вашего приложения, записав память в ОЗУ в файл подкачки. Ничто не выпущено обратно в Windows.

Фактически вы только снова сделали доступ к памяти более медленным, поскольку теперь его нужно читать с диска. Этот метод имеет тот же эффект, что и сведение к минимуму вашего приложения. Затем Windows предполагает, что вы не собираетесь снова использовать приложение в ближайшее время, а также записывает рабочий набор в ОЗУ в файл подкачки. Windows хорошо решает, когда записывать ОЗУ в файл подкачки, и старается хранить в ней максимально используемую память как можно дольше. Это уменьшит размер рабочего набора (запись в файл подкачки), когда останется мало ОЗУ. Я не стал бы возиться с этим, просто чтобы создать иллюзию того, что ваша программа использует меньше памяти, хотя на самом деле она использует столько же, сколько раньше, только теперь доступ к ней медленнее. Память, к которой снова осуществляется доступ, будет снова загружена в ОЗУ и снова увеличит размер рабочего набора. При меньшем объеме памяти размер рабочего набора уменьшается.

Так что нет, это не поможет вам заставить FastMM освободить память. Если ваша цель состоит в том, чтобы ваше приложение использовало меньше памяти, вы должны искать в другом месте. Ищите утечки, ищите фрагменты кучи, ищите оптимизацию, и если вы думаете, что FastMM удерживает вас от этого, вы должны попытаться найти факты, подтверждающие это. Если ваша цель состоит в том, чтобы размер рабочего набора был небольшим, вы можете попытаться сохранить доступ к своей памяти локально. Может быть, FastMM или другой менеджер памяти может помочь вам в этом, но это совсем другая проблема по сравнению с использованием большого количества памяти. И, возможно, эта функция поможет вам решить проблему, с которой вы столкнулись, но я бы использовал ее с осторожностью и, конечно, не использовал бы ее просто для того, чтобы создать иллюзию того, что ваша программа использует мало памяти.

5 голосов
/ 21 декабря 2010

Я согласен с Lars Truijens 100%, если вы этого не сделаете, вы можете проверить использование памяти FasttMM с помощью вызовов FasttMM GetMemoryManagerState и GetMemoryManagerUsageSummary до и после вызова API SetProcessWorkingSetSize.

3 голосов
/ 21 декабря 2010

Вы уверены, что есть проблема?Рабочие наборы могут уменьшиться только тогда, когда действительно не хватает памяти.

2 голосов
/ 27 декабря 2010

Проблема решена:
Мне не нужно использовать SetProcessWorkingSetSize. FastMM в конечном итоге освободит ОЗУ.


Чтобы подтвердить, что это поведение генерируется FastMM (как предложил Барри Келли), я написал вторую программу, которая выделяла МНОГО ОЗУ. Как только в Windows закончилась память, использование памяти моей программы вернулось к своему первоначальному значению.

0 голосов
/ 21 декабря 2010

Я использовал эту функцию только один раз, когда реализовал TWebBrowser. Этот компонент занял у меня так много памяти, даже если я уничтожил экземпляр.

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