Создание эффективных WIN32-приложений с учетом специфики 64-разрядной версии Windows


В какой момент физическую память возвращают системе


На практике уловить момент, подходящий для возврат памяти, ~ штука непростая. Вернемся к примеру с электронной таблицей. Если программа работает на машине с процессором x86, размер каждой страницы памяти — 4 Кб, т e. на одной странице умещается 32 (4096 / 128) структуры CELLDATA. Еели пользователь удаляет содержи мое элемента CellData[0][l], Вы можете вернуть страницу памяти, но только при ус ловии, что ячейки в диапазоне от CellData[0][0] до CellData[0][31] тоже не использу ются. Как об этом узнать? Проблема решается несколькими способами.

  • Несомненно, простейший выход — сделать структуру CELLDATA такой, чтобы она занимала ровно одну страницу. Тогда, как только данные в какой-либо из этих структур больше не нужны, Вы могли бы просто возвращать системе со ответствующую страницу. Даже если бы структура данных занимала не одну, а несколько страниц, возврат памяти все равно был бы делом несложным. Но кто же пишет программы, подгоняя размер структур под размер страниц памяти — у разных процессоров они разные.
  • Гораздо практичнее вести учет используемых структур данных. Для экономии памяти можно применить битовую карту Так, имся массив из 100 структур, Вы создаете дополнительный массив из 100 битов. Изначально все биты сброше ны (обнулены), указывая тем самым, что ни одна структура не используется. По мере заполнения структур Вы устанавливаете соответствующие биты (т. e. приравниваете их единице). Отпала необходимость в какой-то структуре — сбросьте ее бит и проверьте биты соседних структур, расположенных в пре делах той жс страницы памяти. Если и они не используются, страницу можно вернуть системе.
  • В последнем варианте реализуется функция сбора мусора. Как известно, сис тема при первой передаче физической памяти обнуляет всс байты на передан ной странице Чтобы воспользоваться этим обстоятельством, предусмотрите в своей структуре элемент типа BOOL (назвав его, скажем, fInUse ) и всякий раз, когда структура записывается в переданную память, устанавливайте его в TRUE.

При выполнении программы Вы будете периодически вызывать функцию сбо ра мусора, которая должна просматривать все структуры. Для каждой структу ры (и существующей, и той, которая может быть создана) функция сначала определяет, передана ли под нес память; если да, то проверяет значение fInUse. Если оп равен 0, структура не используется; TRUE — структура занята. Прове рив все структуры, расположенные в пределах заданной страницы, функция сбора мусора вызывает VirtualFree, чтобы освободить память, — если, конеч но, па этой странице нет используемых структур.

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

Лично я предпочитаю первые два способа Однако, если Ваши структуры компак тны (меньше одной страницы памяти), советую применять последний метод

{375}




Начало  Назад  Вперед