SetProcessWorkingSetSize - в чем подвох? - PullRequest
15 голосов
/ 19 мая 2011

На сайте About.com я нашел статью , в которой рассказывается, как вы можете управлять памятью своих приложений.

Вот код:

procedure TrimAppMemorySize;
var
  MainHandle : THandle;
begin
  try
    MainHandle := OpenProcess(PROCESS_ALL_ACCESS, false, GetCurrentProcessID) ;
    SetProcessWorkingSetSize(MainHandle, $FFFFFFFF, $FFFFFFFF) ;
    CloseHandle(MainHandle) ;
    Log('Trimmed Memory Successfull!');
  except
    Log('Failed to trim Memory!');
  end;
  Application.ProcessMessages;
end;

Я пыталсяэто работает, отлично работает - даже когда мое приложение что-то делает, и я запускаю щелчки кнопок и т. д., оно все еще делает свое дело, и оно работает как шарм.Я смотрю на мои приложения Использование памяти в Resource Monitor, и, насколько я вижу, все хорошо.

Итак ... В чем подвох?Мы все имеем дело с проблемами с памятью, но так ли уж просто решение?Может кто-нибудь сказать мне, если делать это каждые 60 секунд - это плохо?

Я перезагружусь и попробую запустить мою программу, а также опубликую скриншот моего монитора ресурсов.

Ответы [ 4 ]

36 голосов
/ 19 мая 2011

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

Если ОС требуется больше свободной оперативной памяти, она может определить, какая памятьне использовался в последнее время и постраничать.Это может быть из вашей программы, или из какой-то другой программы.Но если ОС не не требуется больше свободной оперативной памяти, то вы просто принудительно запустили кучу дисковых операций ввода-вывода, о которых никто не просил.

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

Кроме того, обычно неразумно вызывать Application.ProcessMessages, если вы не знаете есть сообщения, которые необходимо обработать вашему основному потоку, которые иначе он не обработал бы сам.Приложение автоматически обрабатывает сообщения, когда больше ничего не нужно делать, поэтому, если вам нечего делать, просто дайте приложению запустить себя.

6 голосов
/ 19 мая 2011

«Подвох» в том, что вы только что сказали операционной системе удалить страницы из вашего рабочего набора, которые фактически находятся в оперативной памяти. Предполагая, что ОС удаляет страницы, на которых нет данных, к которым вы когда-либо обращаетесь снова, проблем нет. Но если он выводит данные, которые понадобятся вашему процессу в будущем, вы только что сказали Windows: «Больше ошибок страницы, пожалуйста».

Основная проблема с этим кодом заключается в том, что вы жертвуете производительностью своего собственного процесса ради остальной части системы (хотя перебор действительно наносит вред всей системе). Это несколько благородно, но явно не "свободна" .

5 голосов
/ 19 мая 2011

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

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

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

На самом деле, при использовании GlobalAlloc / GlobalFree Windows действительно имеет тенденцию сохранять эти блоки памяти подключенными к вашему процессу, у меня был «процесс», по-видимому, использующий 400 МБ памяти, когда он использовал только 40 МБ, потому что GlobalFrees действительно не освобождает память (мы говорим о живом процессе, работающем в фоновом режиме, пока машина работает). В этом случае я счел очень полезным иметь возможность сказать Windows сжать память процесса. Я использую GetProcessMemoryInfo и проверяю текущий .WorkingSetSize, если объем памяти превышает определенный (например, 100 МБ), память сжимается. Да, это приводит к ошибкам страниц при активном использовании памяти, но память освобождается обратно в ядро ​​для использования другими процессами.

Итак, в некоторых случаях я обнаружил, что Windows не выполняет хорошую работу по «сбору мусора» и возврату ресурсов. Рад, что этот звонок доступен, он очень полезен.

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