1.沒有虛拟記憶體的CPU基本不能運作多任務作業系統,不能支援多程序。
2.實作虛拟記憶體技術主要有2種:段式記憶體管理和頁式記憶體管理,目前頁式記憶體管理占主流。
3.頁式記憶體管理将記憶體劃分成大小相同的頁面,每個程序位址空間可以由多個頁面構成,實作程序空間的隔離。
4。為什麼要使用記憶體映射:傳統讀寫檔案的方式過程是open->read/write/lseek->close每一次調用都要執行系統調用,效率極低;如果多個程序要通路同一個檔案,那麼每一個程序都需要在自己的記憶體位址空間維護一個副本,這是一種浪費。而使用mmap将檔案當做記憶體(數組等)操作就不存在這樣的問題。
Linux記憶體映射:Linux核心将整個記憶體位址空間看做是一系列不同的"檔案"映射,不過在這個叫核心對象。Linux加載核心到記憶體的過程就是記憶體映射的過程,甚至加載可執行檔案的過程也是記憶體映射。
5.32位位址虛拟記憶體:32位的虛拟記憶體位址最大能管理4G的實體位址。32位的虛拟位址分成3部分:頁面目錄|頁面表|頁内偏移(10|10|12),頁面目錄能管理1024個頁面表,頁面表能管理1024個頁面(每1024個頁面就分成一個頁面表,頁面表位址放在頁面目錄數組中;1024個頁面的位址放在頁面表數組中)
6.虛拟位址到實體位址的轉換可以有很多應用:程序與程序之間可以虛拟位址相同但實體位址不同,進而達到空間上的真正隔離;利用頁面交換技術可以将一個檔案映射到記憶體中,使得mmap這樣的系統調用得以實作;将相同的虛拟位址轉換成相同的實體位址這樣可以實作資料共享如線程;将硬體裝置的控制存儲區反映到虛拟記憶體中,可以通過記憶體直接控制裝置;...
7.記憶體映射的缺點
記憶體映射可能存在的對存儲實體空間的浪費:每次在不同或相同程序對同一個檔案調用mmap時記憶體映射技術将總是配置設定一個新的頁偏移為0的頁面給程序,這樣導緻多次調用mmap寫入的資料是不連續的。每次調用mmap寫入的資料相對4096取餘數越小,那麼浪費的空間可能越多。
8.mmap系統調用
void* mmap(void* addr,size_t len,int prot,int flag,int filedes,off_t off);
int munmap(void* addr,size_t len); //釋放映射
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <linux/fb.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#define PAGE_SIZE 4096
int main(int argc , char *argv[])
{
int fd;
int i;
unsigned char *p_map;
//打開裝置
fd = open("liujin.txt",O_RDWR);
if(fd < 0)
{
printf("open fail\n");
exit(1);
}
//記憶體映射
p_map = (unsigned char *)mmap(0, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED,fd, 0);
if(p_map == MAP_FAILED)
printf("mmap fail\n");
goto here;
snprintf(p_map+5,10,"bye!");
//列印映射後的記憶體中的前10個位元組内容
for(i=0;i<10;i++)
printf("%c\n",p_map[i]);
here:
munmap(p_map, PAGE_SIZE);
return 0;
}
檢視檔案中的資料:od -tx1 -tc liujin.txt
本文轉自 a_liujin 51CTO部落格,原文連結:http://blog.51cto.com/a1liujin/1880652,如需轉載請自行聯系原作者