Windows для профессионалов

       

Сброс содержимого физической памяти


WINDOWS 98
Windows 98 не поддерживает сброс физической памяти.

Когда Вы модифицируете содержимое страниц физической памяти, система пытает ся как можно дольше хранить эти изменения в оперативной памяти. Однако, выпол няя приложения, система постоянно получает запросы на загрузку в оперативную память страниц из ЕХЕ-файлов, DLL и/или страничного файла. Любой такой запрос заставляет систему просматривать оперативную память и выгружать модифицирован ные страницы в страничный файл.

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

Однако некоторые программы занимают блоки памяти на очень малое время, а потом им уже не требуется их содержимое Для большего быстродействия программа может попросить систему не записывать определенные страницы в страничный файл. И тогда, если одна из этих счраниц понадобится для других целей, системе не при дется сохранять ее в страничном файле, чтo, естественно, повысит скорость работы программы. Такой отказ от страницы (или страниц) памяти называется сбросам фи зической памяти (resetting of physical storage) и инициируется вызовом функции VirtualAlloc с передачей ей в третьем параметре флага MEM_RESET

Если страницы, па которые Вы ссылаетесь при вызове VirtualAlloc, находятся в стра ничном файле, система их удалит. Когда в следующий раз программа обратится к памяти, она получит новые страницы, инициализированные нулями Если же Вы сбра сываете страницу, находящуюся в оперативной памяти, система помечает ее как нс изменявшуюся, и она не записывается в страничный файл.
Но, хотя ее содержимое не обнуляется, читать такую страницу памяти уже пельзя Если системе не понадобится эта страница оператикной памяти, ее содержимое останется прежним. В ином слу чае система может забрать ее в свое распоряжение, и тогда обращение к этой стра нице приведет к тому, что система предоставит программе новую страницу, заполнен ную нулями. А поскольку этот процесс нам не подвластен, лучше считать, что после сброса страница содержит только мусор

При сбросе физической памяти надо учитывать и несколько других моментов. Во первых, когда Вы вызываете VtrtualAlloc, базовый адрес обычно округляется до бли жайшего меньшего значения, кратного размеру страниц, а количество байтов — до ближайшего большего значения, кратного той же величине. Такой механизм округ ления базового адреса и количества байтов был бы очень опасен при сбросе физи ческой памяти; поэтому VirtualAlloc при передаче ей флага MEMRESET округляет эти значения прямо наоборот.Допустим, в Вашей программе есть следующий исходный код:

PINT pnData = (PINT) VirtualAlloc(NULL, 1024, MEM_FlESERVE | MEM_COMMIT, PAGE_READWRITE);

pn[0] = 100;
pn[1] = 200;

VirtualAlloc((PVOID) pnData, sizeof(int), MEM_RESFT, PAGE_READWRITE);

Этот код передает одну страницу памяти, а затем сообщает, что первые четыре байта (sizeof(int)) больше не нужны и их можно сбросить. Однако, как и при любых других действиях с памятью, этa операция выполняется только над блоками памяти, размер которых кратен размеру страниц В данном случае вызов завершится неудач но (VirtualAlloc вернет NULL) Почему? Дело в том, что при вызове VirtualAlloc Вы ука зали флаг MEM_RESET и базовый адрес, переданный функции, теперь округляется до ближайшего большего значения, кратного размеру страниц, а количество байтов — до ближайшего меньшего значения, кратного той же величине Так делается, чтобы исключить случайную потерю важных данных В предыдущем примере округление количества байтов до ближайшего меньшего значения дает 0, а эта величина недо пустима.

Второе, о чем следует помнить при сбросе памяти, — флаг MEM_RESET нельзя комбинировать (логической операцией OR) ни с какими другими флагами. Следую щий вызов всегда будет заканчиваться неудачно:

PVOID pvMem = VirtualAlloc(NULL, 1024, MEM_RESERVE | MEM_COMMIT | MFM_RESET, PAGE_READWRITE);

Впрочем, комбинировать флаг MEM_RESET с другими флагами все равно бессмысленно

И, наконец, последнее. Вызов VirtualAlloc с флагом MEM_RESET требует передачи корректного атрибута защиты страницы, даже несмотря на то что он не будет исполь зоваться данной функцией.


Содержание раздела