5764

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

Реферат

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

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

Русский

2012-12-19

87 KB

36 чел.

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

С приходом 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. Первая из этих функций просто принимает указатель в качестве параметра и возвращает ненулевое значение, если указатель действителен. Другие три функции получают указатель в качестве первого параметра и длину блока памяти в качестве второго параметра. Четвертая функция, кроме того, осуществляет проверку до тех, пока не встретит нулевой ограничитель строки


 

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

5561. Проектирование основных узлов тележки мостового крана 309.5 KB
  Исходные данные: Грузоподъемность G=50 кН Скорость подъема груза VG=20 м/мин Высота подъема груза Н=5 м Скорость перемещения тележки v=25 м/мин ПВ=15% Режим работы - М2; Кратность полиспаста - 4...
5562. Понятие и значение контроля исполнения документов 96.5 KB
  Понятие и значение контроля исполнения документов. Контроль играет важную роль в системе документооборота. Контроль исполнения документов обеспечивает своевременное и качественное решение содержащихся в документе вопросов, охват всех контролируемых ...
5563. Бертольт Брехт. Жизнь и творчество 48.5 KB
  Бертольт Брехт После смерти Бертольта Брехта прошло немало лет. Предсказания недоброжелателей не оправдались: драматургия и поэзия Брехта не только не ушли в прошлое, но с каждым годом приобретают все большее число друзей. Идеи Брехта по-прежнему со...
5564. Архитектура Древней Греции 116.5 KB
  Введение. Архитектура античной Греции, охватывающая в своём развитии в основном VIII-I века до н.э., делится на три периода: архаический, классический и эллинистический. Им предшествовали периоды крито-микенской культуры на территории южной Гр...
5565. Архитектура страны фараонов. Древний Египет 1.82 MB
  Архитектура страны фараонов. Каменная архитектура Египта, о чем свидетельствуют дошедшие до нас памятники древней египетской цивилизации, служила в первую очередь потребностям религии. Жилые дома, в том числе и дворцовые сооружения, строились из лег...
5566. Информация и информационные процессы 272 KB
  Информация и информационные процессы. Определение понятия информации Информация по-латыни означает сообщение. Определения информации. Информация по Шеннону. Информация сообщение, которое уменьшает или устраняет неопределённость в выборе одной возможности из нескольких.....
5567. Учет и анализ финансовых результатов и использования прибыли на примере ОАО Воронежстрой-Холдинг 438.5 KB
  Развитие рыночных отношений требует осуществления новой финансовой политики, усиления и воздействия на ускорение социально-экономического развития России, рост эффективности производства и укрепления финансов государства. Важная роль в обес...
5568. Фильтрация сигналов на фоне помех 153.5 KB
  Фильтрация сигналов на фоне помех. Задачи и методы фильтрации Электрическим фильтром называется пассивный четырехполюсник пропускающий электрические сигналы некоторой полосы частот без существенного ослабления или с усилением, а колебания вне это...
5569. Анализ параметрических цепей 149.5 KB
  Анализ параметрических цепей Общие понятия о параметрических цепях Электрические системы, в которых хотя бы один из параметров (R, L или C) является переменным во времени, называется цепями с переменными параметрами, называется цепями с переменны...