Работа с памятью — различия между версиями

Материал из Викиконспекты
Перейти к: навигация, поиск
Строка 31: Строка 31:
 
[[Файл:vmmap.png|right|thumb|200px|Окно программы VMMap]]
 
[[Файл:vmmap.png|right|thumb|200px|Окно программы VMMap]]
 
Для визуализации адресного пространства можно использовать программу VMMap. В главном окне на диаграмме можно видеть распределение физической памяти адресного пространство между самой программой, подключенными библиотеками, переменными и др. Как видно из скриншота, адресное пространство занимает в физической памяти много меньше, чем предоставленные ему <tex>4GB</tex> (или <tex>2^{64}B</tex> для 64-битных систем), то есть, оно не хранит пустые страницы. Именно поэтому даже на 64-битных системах возможно одновременно запускать несколько процессов, и не бояться того, что объем физической памяти сильно меньше <tex>2^{64}B</tex>.
 
Для визуализации адресного пространства можно использовать программу VMMap. В главном окне на диаграмме можно видеть распределение физической памяти адресного пространство между самой программой, подключенными библиотеками, переменными и др. Как видно из скриншота, адресное пространство занимает в физической памяти много меньше, чем предоставленные ему <tex>4GB</tex> (или <tex>2^{64}B</tex> для 64-битных систем), то есть, оно не хранит пустые страницы. Именно поэтому даже на 64-битных системах возможно одновременно запускать несколько процессов, и не бояться того, что объем физической памяти сильно меньше <tex>2^{64}B</tex>.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
===Архив===
 
Рассмотрим процесс выделения памяти в куче на примере простой программы:
 
 
[[Файл:vmmap_before.png|right|thumb|200px|Память не выделена]]
 
[[Файл:vmmap_after.png||right|thumb|200px|Выделена память под массив]]
 
[[Файл:vmmap_delete.png||right|thumb|200px|Память освобождена]]
 
 
int main()
 
{
 
    int *a = new int [1000000];
 
    delete [] a;
 
    return 0;
 
}
 
 
До выполнения
 
int *a = new int [1000000];
 
куча в адресном пространстве программы занимает <tex>1152kB</tex>, а после выполнения команды - <tex>5060kB</tex>. Значит, память была выделена именно в куче, и объем выделенной памяти равен <tex>3908kB</tex>, что почти в точности соответствует объему массива <tex>int</tex> из <tex>1000000</tex> элементов при выделении <tex>4B</tex> на элемент.
 
 
После выполнения
 
delete [] a;
 
размер кучи снова равен <tex>1152kB</tex>, как и до выделение памяти под массив.
 
 
 
{{TODO|t=Показать в адресном пространстве ран-тайм, библиотеки ядра}}
 

Версия 20:35, 11 июля 2011

Эта статья находится в разработке!

Определение

Адресное пространство
Хранение в физической памяти
(серым выделена заполненная память)

При запуске программы операционная система создает процесс, которому выделяется адресное пространство размером [math]4GB[/math] в 32-битных системах, и [math]2^{64}B[/math] в 64-битных, представляющее из себя массив байт. В этом массиве можно писать и читать данные из любого его места. Ясно, что адресное пространство не может полностью содержаться в физической памяти, поэтому представим, что эта память просто дана каждому процессу, неважно, где она находится. Важно помнить, что у каждого процесса свое адресное пространство, которое не пересекается с адресными пространствами других программ.

Старт процесса

При старте процесса, в адресное пространство помещается код исполняемой программы и код используемых в программе библиотек (например, Kernel.dll). Так же, в адресном пространстве хранится [math]heap[/math], в который будут записываться глобальные переменные.

Хранение адресного пространства

Хранение в физической памяти

Адресное пространство разбито на страницы объемом по [math]4kB[/math]. Для каждой страницы в хранится ее адрес в физической памяти, либо указание, что эта страница пуста (в таком случае хранить саму страницу не надо - поэтому все адресные пространства помещаются в физической памяти). Физическая память формируется из оперативной памяти ([math]RAM[/math]), места на жестком диске, отведенного под [math]swap[/math], и места на жестком диске, где хранится непосредственно код программы.

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

Обращение к адресному пространству

При обращении к той или иной странице, если она не находится в оперативной памяти, она загружается туда. Для этого, либо в оперативке находится свободное место, либо выбирается страница, которая будет выгружена оттуда. Если эта страница уже существует на жестком диске, и не была изменена за время ее пребывания в оперативной памяти, она просто удаляется оттуда; иначе - записывается в [math]swap[/math].

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

Page fault

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

Визуализация адресного пространства с помощью VMMap

Окно программы VMMap

Для визуализации адресного пространства можно использовать программу VMMap. В главном окне на диаграмме можно видеть распределение физической памяти адресного пространство между самой программой, подключенными библиотеками, переменными и др. Как видно из скриншота, адресное пространство занимает в физической памяти много меньше, чем предоставленные ему [math]4GB[/math] (или [math]2^{64}B[/math] для 64-битных систем), то есть, оно не хранит пустые страницы. Именно поэтому даже на 64-битных системах возможно одновременно запускать несколько процессов, и не бояться того, что объем физической памяти сильно меньше [math]2^{64}B[/math].