中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Linux中怎么實現虛擬內存

發布時間:2021-06-24 18:03:31 來源:億速云 閱讀:226 作者:Leah 欄目:數據庫

這期內容當中小編將會給大家帶來有關Linux中怎么實現虛擬內存,文章內容豐富且以專業的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。

  Linux虛擬內存怎么實現

  第一個例子:下面一段程序會打印出程序的pid(進程號)后掛起。

  #include

  #include

  #include

  intmain(){

  printf("run`pmap%d`\n",getpid());

  pause();

  }

  將上面代碼保存成文件mem_munch.c然后運行下面程序編譯并執行:

  $gccmem_munch.c-omem_munch

  $./mem_munch

  run`pmap25681`

  上面進程號是25681,可能你試驗的結果會不太一樣。

  下面我們通過pmap命令來查看一下這個小程序的內存使用情況

  $pmap25681

  25681:./mem_munch

  00000000004000004Kr-x--/home/user/mem_munch

  00000000006000004Kr----/home/user/mem_munch

  00000000006010004Krw---/home/user/mem_munch

  00007fcf5af880001576Kr-x--/lib/x86_64-linux-gnu/libc-2.13.so

  00007fcf5b1120002044K-----/lib/x86_64-linux-gnu/libc-2.13.so

  00007fcf5b31100016Kr----/lib/x86_64-linux-gnu/libc-2.13.so

  00007fcf5b3150004Krw---/lib/x86_64-linux-gnu/libc-2.13.so

  00007fcf5b31600024Krw---[anon]

  00007fcf5b31c000132Kr-x--/lib/x86_64-linux-gnu/ld-2.13.so

  00007fcf5b51200012Krw---[anon]

  00007fcf5b53900012Krw---[anon]

  00007fcf5b53c0004Kr----/lib/x86_64-linux-gnu/ld-2.13.so

  00007fcf5b53d0008Krw---/lib/x86_64-linux-gnu/ld-2.13.so

  00007fff7efd8000132Krw---[stack]

  00007fff7efff0004Kr-x--[anon]

  ffffffffff6000004Kr-x--[anon]

  total3984K

  上面的結果是這個程序的內存使用情況,其實更確切的說是這個程序認為它使用內存的情況。從上面的結果我們能看到,當你訪問libc庫時,實際上是對內存地址00007fcf5af88000的訪問,當你訪問ld庫時,實際上是對內存地址00007fcf5b31c000的訪問。

  上面的輸出可能還比較抽象,下面我們修改一下上面的程序,我們在程序的堆和棧上各放一塊數據。

  #include

  #include

  #include

  #include

  intmain(){

  inton_stack,*on_heap;

  //局部變量是放在棧上的,所以on_stack的地址就是棧的初始地址

  on_stack=42;

  printf("stackaddress:%p\n",&on_stack);

  //malloc的內存是在堆上分配的

  on_heap=(int*)malloc(sizeof(int));

  printf("heapaddress:%p\n",on_heap);

  printf("run`pmap%d`\n",getpid());

  pause();

  }

  編譯運行:

  $./mem_munch

  stackaddress:0x7fff497670bc

  heapaddress:0x1b84010

  run`pmap11972`

  然后再用pmap命令查看一下內存使用:

  $pmap11972

  11972:./mem_munch

  00000000004000004Kr-x--/home/user/mem_munch

  00000000006000004Kr----/home/user/mem_munch

  00000000006010004Krw---/home/user/mem_munch

  0000000001b84000132Krw---[anon]

  00007f3ec4d980001576Kr-x--/lib/x86_64-linux-gnu/libc-2.13.so

  00007f3ec4f220002044K-----/lib/x86_64-linux-gnu/libc-2.13.so

  00007f3ec512100016Kr----/lib/x86_64-linux-gnu/libc-2.13.so

  00007f3ec51250004Krw---/lib/x86_64-linux-gnu/libc-2.13.so

  00007f3ec512600024Krw---[anon]

  00007f3ec512c000132Kr-x--/lib/x86_64-linux-gnu/ld-2.13.so

  00007f3ec532200012Krw---[anon]

  00007f3ec534900012Krw---[anon]

  00007f3ec534c0004Kr----/lib/x86_64-linux-gnu/ld-2.13.so

  00007f3ec534d0008Krw---/lib/x86_64-linux-gnu/ld-2.13.so

  00007fff49747000132Krw---[stack]

  00007fff497bb0004Kr-x--[anon]

  ffffffffff6000004Kr-x--[anon]

  total4116K

  這次多出了上面紅色的一行內容,紅色內容就是堆的起始位置:

  0000000001b84000132Krw---[anon]

  在我們程序運行的輸出里也有一行紅色的輸出,這是這個地址在程序中的內存地址:

  heapaddress:0x1b84010

  這兩個地址基本上是一樣的,其中的anon是Anonymous的縮寫,表明這段內存是沒有文件映射的。

  我們再看上面綠色的兩行,與上面相對應,這兩行分別是用pmap和應用程序看到的棧起始地址:

  00007fff49747000132Krw---[stack]

  stackaddress:0x7fff497670bc

  上面說到的內存使用,都只是程序認為自己對內存的使用,實際上程序在分配內存是不知道系統內存的狀態的。所以上面的輸出都只是從程序自己的角度看到的內存使用狀況。比如在上面的例子中,我們看到程序的內存地址空間是從0×0000000000400000到0xffffffffff600000的所有地址(而0xffffffffff600000到0×00007fffffffffffffff之間的地址是有特殊用處的,這里不多講)。這樣算下來,我們總共可以使用的內存空間有1千萬TB。

  但是實際上目前沒有硬件能有1千萬TB的物理內存。為什么操作系統會如此設計呢?原因有很多,可以看這里,但也正因此,我們可以使用遠遠超出物理內存大小的內存空間。

  內存映射

  內存映射的原理就是讓操作系統將一個文件映射到一段內存中,然后在操作這個文件內存就可以像操作內存一樣。比如我們創建一個完全內容隨機的文件,然后將它用內存映射的方式映射到一段內存空間中。那么我們在這段內存中隨便取一位就相當于取到了一個隨機數。下面就讓我們來做這個實驗,先用下面命令生成一個內容隨機的文件。

  $ddif=/dev/urandombs=1024count=1000000of=/home/user/random

  1000000+0recordsin

  1000000+0recordsout

  1024000000bytes(1.0GB)copied,123.293s,8.3MB/s

  $ls-lhrandom

  -rw-r--r--1useruser977M2011-08-2916:46random

  然后我們用下面程序來將這個文件內容映射到內存,再從中取出隨機數

  #include

  #include

  #include

  #include

  #include

  intmain(){

  char*random_bytes;

  FILE*f;

  intoffset=0;

  //open"random"forreading

  f=fopen("/home/user/random","r");

  if(!f){

  perror("couldn'topenfile");

  return-1;

  }

  //wewanttoinspectmemorybeforemappingthefile

  printf("run`pmap%d`,thenpress",getpid());

  getchar();

  random_bytes=mmap(0,1000000000,PROT_READ,MAP_SHARED,fileno(f),0);

  if(random_bytes==MAP_FAILED){

  perror("errormappingthefile");

  return-1;

  }

  while(1){

  printf("randomnumber:%d(pressfornextnumber)",*(int*)(random_bytes+offset));

  getchar();

  offset+=4;

  }

  }

  然后運行這個程序:

  $./mem_munch

  run`pmap12727`,thenpress

  Linux虛擬內存怎么實現

  下面我們通過一次次的按下回車鍵來從這個文件中讀取隨機數,按下幾次后我們可以再通過pmap來查看其內存空間的情況:

  $pmap12727

  12727:./mem_munch

  00000000004000004Kr-x--/home/user/mem_munch

  00000000006000004Kr----/home/user/mem_munch

  00000000006010004Krw---/home/user/mem_munch

  000000000147d000132Krw---[anon]

  00007fe261c6f000976564Kr--s-/home/user/random

  00007fe29d61c0001576Kr-x--/lib/x86_64-linux-gnu/libc-2.13.so

  00007fe29d7a60002044K-----/lib/x86_64-linux-gnu/libc-2.13.so

  00007fe29d9a500016Kr----/lib/x86_64-linux-gnu/libc-2.13.so

  00007fe29d9a90004Krw---/lib/x86_64-linux-gnu/libc-2.13.so

  00007fe29d9aa00024Krw---[anon]

  00007fe29d9b0000132Kr-x--/lib/x86_64-linux-gnu/ld-2.13.so

  00007fe29dba600012Krw---[anon]

  00007fe29dbcc00016Krw---[anon]

  00007fe29dbd00004Kr----/lib/x86_64-linux-gnu/ld-2.13.so

  00007fe29dbd10008Krw---/lib/x86_64-linux-gnu/ld-2.13.so

  00007ffff29b2000132Krw---[stack]

  00007ffff29de0004Kr-x--[anon]

  ffffffffff6000004Kr-x--[anon]

  total980684K

  上面的輸出和之前的大同小異,但是多出了上面紅色的一行。這是我們上面的隨機文件映射到內存中的內存。我們再使用pmap-x選項來查看一下程序的內存使用,會得到下面的內容,其中RSS(residentsetsize)列表示真實占用的內存。

  pmap-x12727

  12727:./mem_munch

  AddressKbytesRSSDirtyModeMapping

  0000000000400000040r-x--mem_munch

  0000000000600000044r----mem_munch

  0000000000601000044rw---mem_munch

  000000000147d000044rw---[anon]

  00007fe261c6f000040r--s-random

  00007fe29d61c00002880r-x--libc-2.13.so

  00007fe29d7a6000000-----libc-2.13.so

  00007fe29d9a500001616r----libc-2.13.so

  00007fe29d9a9000044rw---libc-2.13.so

  00007fe29d9aa00001616rw---[anon]

  00007fe29d9b000001080r-x--ld-2.13.so

  00007fe29dba600001212rw---[anon]

  00007fe29dbcc00001616rw---[anon]

  00007fe29dbd0000044r----ld-2.13.so

  00007fe29dbd1000088rw---ld-2.13.so

  00007ffff29b200001212rw---[stack]

  00007ffff29de000040r-x--[anon]

  ffffffffff600000000r-x--[anon]

  ----------------------------------

  totalkB980684508100

  如果你的虛擬內存占用(上面的Kbytes列)都是0,不用擔心,這是一個在Debian/Ubuntu系統上pmap-x命令的bug。最后一行輸出的總占用量是正確的。

  現在你可以看一下RSS那一列,這就是實際內存占用。在random文件上,你的程序實際上可以訪問在00007fe261c6f000之前的數十億字節的內存地址,但是只要你訪問的地址超過4KB,那么操作系統就會去磁盤上查找內容。也就是說實際上只有4KB的物理內存被使用了。只有訪問這4KB的東西時,才是真正的內存操作。其它部分雖然你使用的也是內存操作函數來訪問它,但是由于它沒有被加載到內存中,所以在這些內容被訪問的時候,操作系統會先去磁盤讀random中讀取內容到內存中。

  如果我們把程序再修改一下,修改成下面這樣,讓程序把整個random文件都訪問一遍。

  #include

  #include

  #include

  #include

  #include

  intmain(){

  char*random_bytes;

  FILE*f;

  intoffset=0;

  //open"random"forreading

  f=fopen("/home/user/random","r");

  if(!f){

  perror("couldn'topenfile");

  return-1;

  }

  random_bytes=mmap(0,1000000000,PROT_READ,MAP_SHARED,fileno(f),0);

  if(random_bytes==MAP_FAILED){

  printf("errormappingthefile\n");

  return-1;

  }

  for(offset=0;offset<1000000000;offset+=4){   inti=*(int*)(random_bytes+offset);   //toshowwe'remakingprogress   if(offset%1000000==0){   printf(".");   }   }   //attheend,waitforsignalsowecancheckmem   printf("\ndone,run`pmap-x%d`\n",getpid());   pause();   }   現在我們的pmap-x命令就會得到如下輸出:   $pmap-x5378   5378:./mem_munch   AddressKbytesRSSDirtyModeMapping   0000000000400000044r-x--mem_munch   0000000000600000044r----mem_munch   0000000000601000044rw---mem_munch   0000000002271000044rw---[anon]   00007fc2aa33300009765640r--s-random   00007fc2e5ce000002920r-x--libc-2.13.so   00007fc2e5e6a000000-----libc-2.13.so   00007fc2e606900001616r----libc-2.13.so   00007fc2e606d000044rw---libc-2.13.so   00007fc2e606e00001616rw---[anon]   00007fc2e607400001080r-x--ld-2.13.so   00007fc2e626a00001212rw---[anon]   00007fc2e629000001616rw---[anon]   00007fc2e6294000044r----ld-2.13.so   00007fc2e6295000088rw---ld-2.13.so   00007fff037e600001212rw---[stack]   00007fff039c9000040r-x--[anon]   ffffffffff600000000r-x--[anon]   ----------------------------------   totalkB980684977072104   

上述就是小編為大家分享的Linux中怎么實現虛擬內存了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關知識,歡迎關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

泰州市| 乌鲁木齐县| 聊城市| 成安县| 潮州市| 扎囊县| 香河县| 延长县| 卢氏县| 游戏| 隆林| 南漳县| 错那县| 巴林右旗| 永寿县| 南阳市| 湄潭县| 通河县| 且末县| 锦州市| 阳春市| 贵阳市| 九龙城区| 化德县| 宿迁市| 双城市| 西丰县| 石台县| 海城市| 甘南县| 定日县| 大新县| 富锦市| 汾阳市| 六枝特区| 德阳市| 永州市| 邵武市| 深州市| 盐亭县| 海盐县|