5764

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

Реферат

Информатика, кибернетика и программирование

Управление памятью С приходом 32-разрядной Windows управление памятью стало гораздо более приятным, чем раньше. Огромная путаница с сегментами и другими параметрами управления памятью в 16-разрядном режиме сегментной архитектуры Intel-процессоров по...

Русский

2012-12-19

87 KB

39 чел.

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

С приходом 32-разрядной Windows управление памятью стало гораздо более приятным, чем раньше. Огромная путаница с сегментами и другими параметрами управления памятью в 16-разрядном режиме сегментной архитектуры Intel-процессоров полностью и бесповоротно ушла в прошлое

Отдельные адресные пространства

Win32 предусматривает более совершенную схему управления памятью. Двумя ее наиболее отличительными чертами являются возможности

запускать приложения в отдельных адресных пространствах 

и расширять объем доступной для выделения памяти, используя файлы подкачки (свопирование).

Адреса, используемые приложениями Win32, часто называются логическими. Для каждого процесса Win32 доступен полный диапазон 32-разрядных адресов (с определенными ограничениями для некоторых операционных систем, причем эти ограничения не одинаковы для разных платформ Win32).

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

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

С другой стороны

Тот факт, что процессы больше не делят одного логического адресного пространства, усложняет разработку корпоративных процессов. Теперь невозможно передать адрес какого-то объекта в памяти другому процессу, чтобы то смог воспользоваться этим объектом. Этот адрес имеет смысл только в контексте посылающего приложения; в контексте же принимающего приложения он не имеет никакого смысла и представляет собой случайный участок памяти.

К счастью,

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

Виртуальная память

Не все логические адреса приложения действительно отображаются в физическую память.

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

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

ОС и аппаратное обеспечение компьютера выполняют отображение логических адресов. Таблица, часто называемая таблицей страниц, содержит информацию о всех блоках или страницах памяти. В действительности эта таблица отображает блоки логических адресов приложения в блоки физической памяти или участки файла подкачки. Когда логический адрес отображается в реальную физическую память, отображение разыменовывается, и данные считываются или записываются соответственно запросу.

Поскольку эта операция поддерживается аппаратным обеспечением процессора, она не требует никакого дополнительного времени для вычисления адреса памяти.

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

Все это остается незаметным для приложения; единственным признаком того, что блок не находился в физической памяти, является задержка, вызванная операцией подкачки.

Неперемещаемая память

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

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

Отметим, что

Для выделения блоков неперемещаемой памяти в Win32 можно использовать как библиотечные функции C и операторы С++, так и функции Windows, предоставляемые для этих целей системой Win32.

Для примера рассмотрим способы выделения блока неперемещаемой памяти для хранения массива целых чисел размерностью 256 элементов:

 

#define N 256

 

Определим в программе указатель на массив целых чисел следующим образом (указатель p - 32-разрядное число, которое неинициализировано):

 

int *p;

 

Для выделения блоков неперемещаемой памяти и работы с ними рекомендуется использовать обычные библиотечные функции С, так как они просты и привычны.

Можно выделить блок памяти, на который будет указывать p, следующим образом:

 

 p=(int *)malloc(N*sizeof(int)); // или p=(int *)сalloc(N,sizeof(int));

 

При этом  c помощью функции malloc выделяется блок памяти размером 1024 байта (1 КБ), который может хранить 256 32-разрядных целых. Указатель, равный NULL, показывает, что выделение памяти не было успешным.

Можно также выделить такой блок память, используя следующий вызов функции calloc. Два параметра функции calloc перемножаются и в результате получается 1024 байта. Кроме того, функция calloc производит обнуление блока памяти.

Доступ к i-тому элементу массива, хранящегося в блоке памяти, на который ссылается p, осуществляется при помощи операции []:

 

. . . p[i] . . .

 

Если необходимо увеличить размер блока памяти (например, удвоить его), то можно вызвать функцию:

 

 int N_new=N*2;

p=(int *)realloc(p, N_new*sizeof(int));

 

Указатель является параметром функции, и указатель (возможно, отличающийся по значению от первого, особенно, если блок увеличивается) является возвращаемым значением функции realloc. Этот пример показывает, что операционная система может перемещать блок в рамках виртуальной памяти.

После окончания работы с памятью необходимо вызвать функцию, освобождающую блок памяти:

 

free(p);

 

 Замечание. Только указанные четыре функции (malloc, calloc, realloc, free) определены в стандарте ANSI языка C. Часто производители компиляторов реализуют несколько большее количество функций, наиболее распространенной из которых является функция _msize, возвращающая размер выделенного блока.

Помимо библиотечных функций С для выделения блоков неперемещаемой памяти и работы с ними можно использовать и операторы языка C++.

Приведем пример их использования:

 

p=new int[N];   // выделение блока памяти и инициализация указателя

 if(p!=NULL)

{

 . . . p[i] . . . // использование значений элементов массива

 delete []p;   // освобождение блока памяти

}

 

Для выделения блоков неперемещаемой памяти и работы с ними можно использовать вызовы функций ядра Windows. Ниже приведена функция Windows для выделения блока неперемещаемой памяти для указателя на целые:

 

 int *p; // объявление указателя

. . .

p=(int *)GlobalAlloc(GPTR, N*sizeof(int));

 

Функция GlobalAlloc имеет два параметра: набор флагов и размер выделяемого блока в байтах. Если первый параметр функции GlobalAlloc задать нулевым, то это аналогично использованию флага GMEM_FIXED (равен нулю). Такой вызов функции GlobalAlloc эквивалентен вызову функции malloc. Можно также использовать флаг GMEM_ZEROPOINT для обнуления всех байтов выделяемого блока памяти. Флаг GPTR включает в себя флаги GMEM_FIXED и GMEM_ZEROPOINT.

Виртуальный адрес, который выдает функция GlobalAlloc в приведенном примере, может использоваться в программе для доступа к выделенной памяти. Значение NULL говорит о том, что имеющейся в распоряжении памяти для выделения недостаточно.

Для каждой функции (за исключением одной), начинающейся со слова Global, существует другая, начинающаяся со слова Local. Эти два набора в Win32 идентичны. Два различных слова сохранены для совместимости с предыдущими версиями Windows, где функции Global возвращали дальние указатели, а функции Local - ближние.

Доступ к i-тому элементу массива, хранящегося в блоке памяти, на который ссылается p, осуществляется при помощи операции []:

 

. . . p[i] . . .

 

Имеется также функция изменения размера блока памяти:

 

 int N_new=N*2;

p=(int *)GlobalReAlloc(p, N_new*sizeof(int), GMEM_FIXED);

 

Можно использовать флаг GMEM_ZEROPOINT для обнуления добавляющихся в блок памяти байтов, если блок расширяется.

Существует функция, возвращающая размер блока памяти и функция освобождения памяти:

 

 DWORD dwSize=GlobalSize(p);

и

GlobalFree(p);

 

Перемещаемая память

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

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

Блок перемещаемой памяти характеризуется тем, что его виртуальный адрес может в любое время измениться даже без физического перемещения блока памяти. Блок перемещаемой памяти можно выделить при помощи функция GlobalAlloc, передавая ей в качестве первого параметра GMEM_MOVEABLE или комбинированный флаг GHND, включающий в себя флаги GMEM_ MOVEABLE и GMEM_ZEROPOINT для обнуления блока памяти.

Флаг GMEM_MOVEABLE позволяет перемещать блок памяти в виртуальной памяти. Это не обязательно означает, что блок памяти будет перемещен в физической памяти, но адрес, которым пользуется программа для чтения и записи, может измениться.

Рассмотрим, как создается и используется блок перемещаемой памяти. Первым делом определяются указатель и переменная типа GLOBALHANDLE (описатель, селектор блока памяти):

 

#define N 256

. . .

int *p; GLOBALHANDLE hGlobal; // указатель и описатель (неинициализированные)

 

Затем выделяется память, например, так:

 

 hGlobal=GlobalAlloc(GHND, N*sizeof(int));

 

Перед тем, как обратиться к памяти, нужно зафиксировать блок с использованием вызова:

 

 p=(int *)GlobalLock(hGlobal);

 

Эта функция преобразует описатель памяти в указатель. Пока блок зафиксирован, Windows не изменяет его виртуальный адрес.

Доступ к i-тому элементу массива, хранящегося в блоке памяти, на который теперь ссылается p, осуществляется при помощи операции []:

 

. . . p[i] . . .

 

После работы с зафиксированным блоком с него необходимо снять фиксацию:

 

GlobalUnlock(hGlobal);

 

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

Когда нужно освободить память, следует вызвать функцию GlobalFree с параметром-описателем, а не с указателем (к этому времени с блока должна быть снята фиксация, если она производилась):

 

GlobalFree(hGlobal);

 

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

Перемещение блока в виртуальной памяти не есть перемещение байтов с одного места на другое - производятся только манипуляции с таблицами страниц. Единственной причиной для выделения перемещаемой памяти служит предотвращение фрагментации виртуальной памяти.

 Замечание. Для того чтобы получить описатель блока памяти, на который указывает указатель p, необходимо использовать функцию:

 

GLOBALHANDLE hGlobal=GlobalHandle(p);

 

Удаляемая память

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

Например, блоки памяти, содержащие код, являются удаляемыми и защищенными от записи. Следовательно, быстрее загрузить код из исходного файла .exe, чем записывать его на диск, а затем вновь загружать с диска.

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

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

 

GlobalDiscard(hGlobal);

 

Отображаемые в память файлы

При работе с Win32 существует возможность читать и записывать данные в файл так, как будто это блок памяти. Этот прием часто рекомендуется использовать также при разделении памяти между двумя и более процессами.

Сначала создается обычный файл hFile с использованием функции CreateFile.а Если необходимо осуществить доступ к части файла, то вызывается функция MapViewOfFile. После этого можно использовать указатель, возвращаемый функцией, для доступа или модификации данных в файле, отображаемом в память.

 Замечание. Возникает вопрос, не излишне ли использовать дисковый файл, если необходимо лишь передать несколько байт между приложениями? В действительности нет необходимости явно открывать и использовать дисковый файл для получения отображения в памяти.  

Приложения могут передать специальное значение дескриптора равное 0хFFFFFFFF в функцию CreateFileMapping для получения отображения непосредственно в системный страничный файл. Это, по сути, создает блок разделяемой между приложениями памяти.

Другие функции работы памятью

Win32 также содержит следующие функции для работы с памятью:

FillMemory -заполнение конкретным байтом,

ZeroMemory - обнуление памяти, 

CopyMemory и MoveMemory - копируют данные из одной области в другую (если эти области перекрываются, то функция CopyMemory может работать некорректно, вместо нее нужно использовать функцию MoveMemory).

Для того чтобы проверить, возможен ли доступ по какому-либо указателю (т.е. действителен тот или иной указатель) есть ряд функций: IsBadCodePtr, IsBadReadPtr, IsBadWritePtr и IsBadStringPtr. Первая из этих функций просто принимает указатель в качестве параметра и возвращает ненулевое значение, если указатель действителен. Другие три функции получают указатель в качестве первого параметра и длину блока памяти в качестве второго параметра. Четвертая функция, кроме того, осуществляет проверку до тех, пока не встретит нулевой ограничитель строки


 

А также другие работы, которые могут Вас заинтересовать

70246. Якість продукції та методи її оцінювання 345.5 KB
  Основні поняття і визначення якості товарів і послуг Світовий досвід показує що в умовах глобальної конкуренції і відкритої ринкової економіки якість товарів і якість виробничих процесів є визначальним результатом і стратегічним напрямком діяльності будьякої господарської одиниці.
70247. Товари та послуги в маркетинговій діяльності. Економічна сутність товара і послуги 282 KB
  Класичне визначення товару залишається безсумнівно справедливим і в маркетингу. З розвитком та ускладненням економічних відносин наповнялося новим змістом і поняття товару. При цьому існуючі розходження в розумінні сутності товару пов’язані з тим з якої позиції він розглядається.
70248. Ціна в системі ринкових характеристик товару. Значення ціни в системі ринкових відносин 275 KB
  Важливою й актуальною проблемою для будьякого підприємства є встановлення раціональної ціни на вироблені і або реалізовані товари та послуги. Суть цілеспрямованої цінової політики в маркетингу полягає в тому щоб установлювати на товари підприємства такі ціни і так варіювати ними залежно...
70249. Сутність і значення маркетингу в сучасній економіці. Сутність і роль маркетингу в сучасній економіці 215.5 KB
  Сутність і роль маркетингу в сучасній економіці Термін маркетинг від англ. Початок розвитку маркетингу як прикладної наукової дисципліни пов’язують з Пенсильванським університетом США де в 1905 році В. Ватлер почав вести постійний курс âМетоди маркетингуâ в університеті Вісконсіна США.
70250. Товарні марки та упаковка. Товарна марка як частина товару 526.5 KB
  Такі складові товарної політики як розробка товарної марки і управління марочним капіталом стали постійним і важливим елементом стратегічного маркетингу виробників і продавців. Посилення комунікативного впливу на споживачів завдяки автоматичній рекламі товару в міру...
70251. Життєвий цикл товару. Економічний зміст життєвого циклу товару 228 KB
  З поняттям життєвий цикл товару пов’язують концепцію що характеризує економічний цикл життя товару від його розробки до моменту вилучення з продажу. З точки зору маркетингу більш актуальний цикл життя товару на ринку який за періодом часу коротший за економічний цикл оскільки не містить...
70252. Планування нової продукції і розробка товару. Значення розробки нової продукції для товарної політики підприємств 341.5 KB
  Відновлення може виявитися також у новій конструкції товару у новому виробничому процесі у новому маркетинговому підході до системи просування товару на ринок. Розвиток нових технологій не тільки активізує процес створення нових товарів але й веде до істотного скорочення життєвого циклу товару.
70253. Цільовий ринок товару і методика його вибору. Зміст маркетингової діяльності щодо дослідження ринку 295 KB
  Ефективні та виважені маркетингові рішення в рамках товарної політики підприємства можуть бути прийняті лише на основі достовірних маркетингових досліджень. Загальне завдання системи маркетингових досліджень можна конкретизувати в наступних трьох завданнях: допомога в розумінні ринку...
70254. Формування попиту на ринку окремого товару. Потреби, попит та пропозиція, їх економічна сутність 272.5 KB
  Маркетинговий підхід до рішення завдань товарної політики які постають перед підприємствами і підприємцями заснований на вивченні формуванні і задоволенні потреб тих економічних суб’єктів що обрані як потенційні споживачі. Таким чином потреби можна розглядати із самих різних боків...