Управление памятью в операционной системе WINDOWS, страница 2

Можно попробовать выделять память небольшими участками по мере необходимости. Например, сначала выделить участок памяти для 30 секунд видео, затем, используя функцию realloc, добавить к этому участку еще один участок для следующих 30 секунд и т. д. Однако при этом нельзя быть уверенным в том, что выделяемая память будет непрерывна. Если между обращениями к realloc другая функция или другой программный поток получат в индивидуальное пользование фрагмент памяти, физически расположенный поблизости от места, где хранится записываемый в память видеоклип, дальнейшее расширение области памяти для хранения видео будет осложнено. В этой ситуации, чтобы обеспечить непрерывность участка памяти, функция realloc будет вынуждена переместить уже записанную часть видеоклипа в другую область адресного пространства для того, чтобы продолжить ее расширение. Представьте, что к этому моменту вы уже успели записать 25 Мбайт видео. Перемещение такого объема данных в процессе оцифровки может оказаться крайне нежелательным.

Механизмы управления памятью, встроенные в Windows, позволяют решить эту проблему. Помимо этого Windows позволяет выделять память только для чтения, а также использовать так называемые «разреженные»  массивы (sparse arrays).

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

Страничная организация памяти

В наше время в основе многих компьютерных архитектур располагается специальный механизм управления памятью, который называют MMU (Memory Management Unit — устройство управления памятью). На компьютерах, оснащенных процессором Pentium, механизм MMU является неотъемлемой частью CPU. MMU осуществляет преобразование линейных адресов виртуального адресного пространства каждого из работающих на компьютере процессов в адреса физической оперативной памяти, реально установленной на компьютере. Как мы знаем, в Windows 2000 каждый процесс обладает виртуальным адресным пространством размером 4 Гбайт, однако, как правило, только часть этого пространства отображается на физическую оперативную память, реально установленную на компьютере.

Благодаря MMU осуществляется поддержка многих чрезвычайно эффективных и удобных технологий. Например, если программа обращается к области памяти с адресом 0,механизм MMU может перенаправить это обращение по адресу, к примеру, 16384. Таким образом, программа будет думать, что осуществлено чтение (или запись) байта по нулевому адресу, а на самом деле этот байт располагается по адресу 16384. Другая программа может также обратиться по адресу 0, однако MMU осуществляет преобразование адресов для каждой из программ по-разному. При обращении к ячейке с нулевым адресом второй программы он перенаправляет это обращение по совершенно другому адресу (например, 32768). Иными словами, благодаря MMU каждый процесс, работающий в системе, думает, что обладает собственным индивидуальным адресным пространством от 0 до 4 Гбайт, хотя на самом деле данные, принадлежащие этим процессам, хранятся в разных областях одного и того же физического адресного пространства.

Если бы MMU мог осуществить перенаправление каждого байта ОЗУ по другому адресу, его таблицы соответствия программных адресов физическим были бы чрезмерно большими. Вместо этого MMU рассматривает всю оперативную память как набор небольших блоков, которые называют страницами, и осуществляет трансляцию адресов в соответствии с границами этих страниц. MMU, встроенный в процессоры типа Pentium, использует страницы размером 4 Кбайт (другие процессоры могут использовать другой размер страниц; узнать этот размер можно при помощи функции GetSystemInfo). Таким образом, если ячейке памяти с виртуальным адресом 0 соответствует ячейка памяти с физическим адресом 16384, то ячейке памяти с виртуальным адресом 1 всегда будет соответствовать ячейка памяти с физическим адресом 16385 и т.д. Однако ячейке памяти с виртуальным адресом 4096 может соответствовать совершенно иной, отличный от 20480 (16384+4096) физический адрес, ведь эта ячейка принадлежит другой странице памяти.