Программа-пример VMAIloc
Эта программа, "15_VMAllocexe" (см листинг на рис 15-1), демонстрирует применение механизма виртуальной памяти для управления массивом структур. Файлы исходного кода и ресурсов этой программы находятся в каталоге 15-VMAlloc на компакт диске, прилагаемом к книге После запуска VMAlloc на экране появится диалоговое окно, показано ниже.
Изначально для массива не резервируется никакого региона, и все адресное пространство, предназначенное для нею, свободно, что и отражено па карте памяти. Если щелкнуть кнопку Reserve Region (50,2KB Structures), программа VMAlloc вызовет VtrtualAlloc для резервирования региона, что сразу отразится на карте памяти. После этого сланут активными и остальные кнопки в диалоговом окне.
Теперь к поле можно ввести индекс и щелкнуть кнопку Use. При этом по адресу, где должен располагаться указанный элемент массива, передается физическая память. Долее карта памяти вновь перерисовывается и уже отражает состояние региона, за резервированного под весь массив. Когда Вы, зарезервировав регион, вновь щелкнете кнопку Use, чтобы пометить элементы 7 и 46 как занятые, окно (при выполнении программы на процессоре с размером страниц по 4 Кб) будет выглядеть так:
ЛюбоЙ элемент массива, помеченный как занятый, можно освободить щелчком кнопки Clear. Но это не приведет к возврату физической памяти, переданной под элемент массива. Дело в том, что каждая страница содержит несколько структур и освобождение одной структуры не влечет за собой освобождения других. Если бы память была возвращена, то пропали бы и данные, содержащиеся в остальных структурах. И поскольку выбор кнопки Clear никак не сказывается на физической памяти региона, карта памяти после освобождения элемента не меняется.
Однако освобождение структуры приводит к тому, что ее элемент fInUse устанавливается в FALSE. Это нужно для того, чтобы функция сбора мусора могла вернуть неиспользуемую больше физическую память. Кнопка Garbage Collect, если Вы еще не догадались, заставляет программу VMAlloc выполнить функцию сбора мусора.
Для упрощения программы я не стал выделять эту функцию в отдельный поток.
Чтобы посмотреть, как работает функция сбора мусора, очистите элемент массива с индексом 46. Заметьте, что карта памяти пока не изменилась. Теперь щелкните кнопку Garbage Collect. Программа освободит страницу, содержащую 46-й элемент, и карта памяти сразу же обновится, как показано ниже. Заметьте, что функцию Garbage Collect можно легко использовать в любых других приложениях. Я реализовал ее так, чтобы она работала с массивами структур данных любого размера; при этом структура не обязательно должна полностью умещаться на странице памяти. Единственное требование заключается в том, что первый элемент структуры должен быть значением типа BOOL, которое указывает, задействована ли данная структура.
И, наконец, хоть это и не видно на экране, закрытие окна приводит к возврату всей переданной памяти и освобождению зарезервированного региона.
Но есть в этой программе еще одна особенность, о которой я пока не упоминал. Программе приходится определять состояние памяти в адресном пространстве региона в трех случаях:
Все эти проверки VMAlloc осуществляет через функцию VirtualQuery, рассмотренную в предыдущей главе.
VMAIIoc