SetProcessWorkingSetSize - какой улов?

Я нашел статью на сайте 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;

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

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

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

Ответы

Ответ 1

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

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

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

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

Ответ 2

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

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

Ответ 3

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

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

Ответ 4

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

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