Пользователям Web, вероятно, не раз приходилось видеть всплывающую рекламу, в которой содержатся предложения «дефрагментировать память» или «снизить до минимума сбои приложений и системы и освободить неиспользуемую память». Ссылки указывают на утилиты, с помощью которых можно решить эти и другие проблемы всего за 9,95, 14,95 или 29,95 долл. Звучит неправдоподобно? Действительно, на первый взгляд утилиты полезны, но на самом деле оптимизаторы оперативной памяти в лучшем случае не оказывают никакого влияния, а в худшем — приводят к заметному снижению производительности.

Буквально десятки так называемых «оптимизаторов памяти» распространяются бесплатно и на коммерческой основе. Какие же функции на самом деле выполняют эти утилиты и каким образом их производители обманывают пользователей, заставляя поверить в эффективность своих программ? Заглянем внутрь оптимизатора памяти и разберемся, какие манипуляции производятся с видимыми пользователю счетчиками памяти Windows.

Пользовательский интерфейс оптимизатора

Оптимизаторы памяти, как правило, выводят на экран диаграмму Available Memory (доступная память) с линией, указывающей порог, при превышении которого утилита вступает в действие. Другая линия, как правило, показывает объем памяти, который оптимизатор попытается освободить. Обычно пользователь может настроить один или оба уровня, а также запускать процедуру оптимизации памяти вручную или по расписанию. Некоторые инструменты отображают активные процессы в системе.

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

Управление памятью Windows

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

Адресное пространство виртуальной памяти объемом 4 Гбайт в 32-разрядных машинах Windows, как правило, делится поровну между процессами и операционной системой. Таким образом, процессу может быть выделено до 2 Гбайт виртуальной памяти, в зависимости от величины доступного пространства. Общий размер виртуальной памяти, выделяемой всем процессам, не может превышать сумму страничных файлов и большей части физической памяти (операционная система резервирует некоторую часть физической памяти).

Учитывая, что при наличии достаточно большого страничного файла процессам может быть выделена виртуальная память, превышающая емкость физической памяти компьютера, подсистема Windows Memory Manager должна делить физическую память между процессами и кэшированными файлами данных Cache Manager. Как показано на рис. 1, Memory Manager выделяет каждому процессу (например, Microsoft Word, Notepad, Windows Explorer) часть физической памяти, которая известна как рабочий набор (working set) процесса. Сохраняемым на диске фрагментам ядра, драйверам и буферам памяти ядра, называемым страничным пулом, а также физической памяти, управляемой Cache Manager, назначается собственный рабочий набор System.

Memory Manager расширяет и сжимает рабочие наборы System и процессов в соответствии с потребностью процессов в быстром доступе к программному коду и данным. Из-за особенностей аппаратных схем компьютера Windows управляет рабочими наборами и виртуальной памятью, разделяя их на блоки страничного размера. В 32-разрядных процессорах x86 размер страницы обычно составляет 4096 байт. Однако при возможности в целях оптимизации операционная система и программы, занимающие много памяти, используют большие 4-мегабайтные страницы.

Если процесс обращается к странице виртуальной памяти, которой нет в рабочем наборе, то возникает исключительная ситуация — ошибка обращения к странице. При этом Memory Manager выделяет страницу свободной физической памяти для хранения данных, к которым обратился процесс. Кроме того, Memory Manager может расширить рабочий набор процесса, добавив к нему страницу. Но если размеры рабочего набора достаточно велики, то Memory Manager заменяет страницу, находящуюся в рабочем наборе, новой страницей. Из рабочего набора удаляется страница, с момента обращения к которой прошло больше всего времени (предполагается, что вероятность обращения процесса к этой странице самая низкая).

При удалении страницы из рабочего набора процесса Memory Manager должен решить, что с ней делать. Если страница была изменена, то Memory Manager сначала заносит ее в список измененных страниц, которые в конечном итоге будут записаны в страничный файл или в отображаемые в память файлы, которым соответствуют страницы. Memory Manager перемещает страницы из списка измененных страниц в пул, называемый резервным списком (standby list). Неизмененные страницы направляются прямо в резервный список. Таким образом, резервный список можно рассматривать как кэш данных файлов.

Доступная память

Ранее уже отмечалось, что Memory Manager выделяет страницу свободной физической памяти процессу, в котором произошла ошибка обращения к странице, но не было дано определение доступной памяти. Резервный список — часть физической памяти, которую Memory Manager рассматривает как доступную. Другие пулы, составляющие доступную память, — это страницы с данными освобожденной виртуальной памяти (например, страницы с данными, принадлежащими завершенным процессам) и страницы, освобожденные и впоследствии заполненные нулевыми данными низкоприоритетным потоком zero page диспетчера памяти. Страницы этих типов хранятся в списке свободных страниц и в списке обнуленных страниц Memory Manager соответственно.

Рисунок 2. Рабочие наборы и переходы между списками страниц

На рис. 2 показаны переходы между рабочими наборами и списками страниц. Один раз в секунду системный поток активизируется и вызывает диспетчера рабочих наборов Memory Manager для анализа рабочих наборов процессов и System. Если пространство доступной памяти мало, то диспетчер рабочих наборов удаляет страницы из процессов, для которых число ошибок при обращениях к страницам было невелико. Удаленные страницы направляются в измененный или резервный список и пополняют доступную память. Важный побочный эффект этого механизма настройки состоит в том, что если системе необходима память для других процессов, то Memory Manager забирает страницы из рабочих наборов неактивных процессов. Таким образом, эти рабочие наборы постепенно исчезают, и в конечном итоге процессы, не проявлявшие активности в течение достаточно длительного времени, освобождают всю физическую память.

Если процессу требуется новая страница физической памяти, то Memory Manager сначала выясняет, не находится ли нужная процессу страница в списках резервных или измененных страниц. Если страница была удалена из рабочего набора и не использовалась для других целей, то она находится в одном из этих списков. Процедура возвращения страницы в рабочий набор процесса называется «программной» страничной ошибкой (soft page fault), так как, в отличие от аппаратных страничных ошибок, она не связана с операцией чтения из страничного файла или другого файла на диске.

Если страницы нет в резервном списке или в списке измененных страниц, то Memory Manager извлекает страницу из списка, в котором она находится, проверяя сначала список свободных, затем обнуленных страниц и, наконец, резервный список. Если свободной памяти нет, то Memory Manager запускает диспетчер Balance Set Manager, чтобы изменить рабочие наборы и пополнить один из трех списков доступной памяти. Если Memory Manager приходится удалять страницу из обнуленного, свободного или резервного списка для повторного использования, то он определяет, каким образом следует обратиться к целевому программному коду или данным. В частности, Memory Manager может прочитать данные из страничного файла или исполняемого образа либо создать нулевые данные — если приложение записывает свежие данные, а страница извлечена не из списка обнуленных страниц.

Создание доступной памяти

Зная принципы работы Memory Manager, можно приступить к изучению механизма действия оптимизаторов памяти. Значение доступной памяти, отображаемое оптимизатором оперативной памяти, есть та самая величина, которую Task Manager показывает в строке Available раздела Physical Memory на вкладке Performance (экран 1). Данная величина представляет собой сумму размеров страниц в резервном, обнуленном и свободном списках. System Cache — сумма размеров страниц в резервном списке и рабочем наборе System. В Windows NT 4.0 и более ранних версиях File Cache отображает размер только рабочего набора System.

Экран 1. Счетчик доступной памяти в Task Manager

Оптимизаторы оперативной памяти используют особенности поведения Memory Manager, выделяя, а затем освобождая большие пространства виртуальной памяти. На рис. 3 показаны результаты работы оптимизатора оперативной памяти в системе. Первая горизонтальная полоса отображает рабочие наборы и доступную память до оптимизации. Вторая полоса показывает, что оптимизатор оперативной памяти создает значительную нагрузку на память, вызывая многочисленные ошибки обращения к страницам за короткое время. В ответ Memory Manager увеличивает рабочий набор оптимизатора. Расширение рабочего набора оптимизатора происходит за счет доступной памяти и, когда доступной памяти мало, за счет рабочих наборов других процессов. На третьей полосе видно, как после освобождения оптимизатором занятой им памяти Memory Manager перемещает все страницы, выделенные оптимизатору оперативной памяти, в свободный список. Таким образом увеличивается объем доступной памяти. Большинство оптимизаторов скрывают быстрое уменьшение доступной памяти на первом этапе, но если запустить Task Manager во время оптимизации, то часто можно увидеть, как сокращается память.

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

Прочие возможности оптимизаторов оперативной памяти

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

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

Непрерывная область памяти повышает быстродействие в одном случае: если в целях увеличения скорости кэш-памяти процессора Memory Manager использует механизм page coloring для назначения страниц, выделяемых процессам из списков свободных или обнуленных страниц. Однако негативные последствия удаления из памяти ценных программ и данных значительно перевешивают выигрыш, который можно извлечь из непрерывного пространства физической памяти.

И наконец, поставщики часто утверждают, что оптимизаторы оперативной памяти возвращают память, потерянную из-за утечек. Данное утверждение в большей степени, чем другие, вводит потребителей в заблуждение.

Memory Manager все время отслеживает физическую и виртуальную память, используемую процессом. Однако если процесс выделяет память, а затем не освобождает ее из-за ошибки (это явление известно как утечка), то Memory Manager не может определить, что выделенная память не будет использоваться вновь, и вернет ее только после того, как процесс завершит работу.

Даже если допускающий утечку процесс работу не завершит, Memory Manager в конечном итоге удалит из рабочего набора процесса все физические страницы, связанные с потерянной виртуальной памятью. Этот процесс отправляет утерянные страницы в страничный файл, и система может использовать физическую память для других целей. Таким образом, утечка не оказывает особого влияния на доступную физическую память. В основном утечка отражается на потреблении виртуальной памяти (для обозначения которого в Task Manager используются термины PF Usage и Commit Charge). У любой утилиты есть только один способ повлиять на потребление виртуальной памяти — закрыть процессы, занимающие память.

В заключение хочу сказать, что до сих пор я не видел ни одного оптимизатора, возможности которого соответствовали бы обещаниям его создателей. На Web-узлах поставщиков часто бывают скрыты длинные и запутанные отказы от обязательств, в которых говорится то же самое, о чем я рассказал в статье, — продукт может не оказать никакого влияния на производительность и даже ухудшить ее. Не обязательно знать, как эти продукты используют Memory Manager для раздувания заметных параметров памяти с броскими названиями. Простой здравый смысл подсказывает, что если бы оптимизация оперативной памяти была возможна (и была под силу столь многим мелким фирмам), то программисты Microsoft давно бы интегрировали эту технологию в ядро операционной системы.

Марк Русинович (mark@sysinternals.com) - редактор Windows & .NET Magazine и докладчик на Windows & .NET Magazine Connections 2004. Соавтор Inside Windows 2000, 3rd edition (Microsoft Press) и автор многих популярных утилит для Windows, включая Process Explorer и Regmon