虛擬內存的作用

發表于:2014-01-22來源:IT博客大學習作者:楊鎮鋒點擊數: 標簽:虛擬內存
直譯是虛擬內存,對于WINDOWS下的用戶,直觀的感受是,在硬盤上開辟一片區域當內存用。而LINUX下的用戶,直觀感受是,一個進程的內存占用,分虛擬內存與物理內存。

  直譯是虛擬內存,對于WINDOWS下的用戶,直觀的感受是,在硬盤上開辟一片區域當內存用。而LINUX下的用戶,直觀感受是,一個進程的內存占用,分虛擬內存與物理內存。

  虛擬內存的作用,個人理解,主要有幾個:

  (1)簡化開發,每個進程都可以認為自己占有整個內存,這對多任務系統很重要,早期有些系統,甚至需要使用相對地址,再根據代碼載入內存的基準地址,算出真正要訪問哪個內存地址

  (2)利用多級存儲系統,把硬盤或別的存儲介質當內存使用,在內存不足的系統,這點很重要,線上服務的機器,為了確保響應速度,一般會關閉這個功能

  (3)節省內存,用戶往往事先不知道需要用多少內存,所以會申請一個很大的數組,會造成浪費,所以剛開始的時候,是只分配虛擬內存,當用到的時候才分配物理內存

  對于第二點,對于多級存儲系統,其實一般就兩級,內存跟硬盤,還需要有一個淘汰策略決定什么內存放哪。如果有三種存儲介質,比如SSD,LINUX 在這種情況下會出錯。如果內存不夠,而硬盤上開了SWAP分區(也就是虛擬內存了),LINUX的行為是,先把數據讀到SWAP,然后再從SWAP讀數據,SSD白搭了。

  具體實現的時候,是把內存分頁,一個頁面一般是4K,當訪問一個還沒分配出來的內存單元的時候,會把該內存單元所在的整個頁面都分配出來。這樣一個好處是,邏輯上連續的虛擬地址,可以映射成不連續的物理地址。

  MMAP實現的時候,就是以頁為單位分配內存。以前出過一次CORE,是用MMAP讀文本文件,用了很多字符串函數,默認輸入數據是以'\0'結束的。問題是文本文件里是不可能有'\0'的,這個'\0'其實是mmap讀入數據的時候,對一個內存頁里空的數據都置0。運氣不好的時候,文件大小正好是 4K的整數次倍,后面就沒有'\0',就一直往后讀,最后CORE了

  不是所有的內存都分頁的,有部分內存是被OS強制占用,以確保性能。

  還有一種實現方式是把內存分段,不過已經不常用了。

  在運行過程中,需要把虛擬地址轉換為物理地址。程序運行的時候,如果訪問了非法內存,這時候會CORE掉,并且報SEG ERROR,就是在這個階段探測出來的。雖然內存是分頁的,但是在上層還是會維護一些段的結構以標記哪些內存是可以訪問,哪些不可以。

  為了提高速度,在CPU里有個部件專門負責轉換,稱為MMU。

  想像一下最簡單的轉換算法,虛擬內存地址的低位表示頁內的偏移,高位表示頁ID,在內存里開辟一片連續區域,存儲每一個頁面對應的物理頁面地址。

  這個方法主要的問題是,太耗內存了。虛擬地址空間往往很大,會超過物理內存的大小,假設用40個BIT表示,一個頁面4K,則有2^28個頁面,這個消耗很大。

  虛擬地址的空間很大,但是最終會用到的很少,不會超過RAM的大小。解決方案是用多層表。先把整個空間分成N段(N比較小),如果這一段里面有數據,則把這一分再切割成N份,繼續遞歸,一般只切割4層。對于一大片沒用到的空間,在表里很高的一層就統計出沒有數據,不用分配出下一層的表了。為了減少多層表里節點的內存開銷,上層需要把虛擬地址盡可能地連續。

  這個解決方案明顯的問題是,作一次轉換需要多次訪問內存,就算把這個表放在CACHE里,多次訪問的開銷還是明顯的,因為這四次訪問不能并行,每一步都要等上一步有結果才能進行。

  所以解決方案是增加一個CACHE,稱為TLB,把轉換的最終結果CACHE住。

  為了提高TLB的命中率,最簡單的方法是,減少需要CACHE的數據,就是把內存頁增大。當然這樣可能會造成內存浪費,所以一般不這樣做。

  在MISS之后,為了減少開銷,可以的把多層表的層數減少,這樣步驟會變少,但是內存占用也可能增加。

  前面說了這么多理論的。在作代碼優化的時候,大部分的教材是不會說怎么檢測TLB MISS的,用VTUNE的時候,一般也不會這樣提示。用VTUNE是可以檢測TLB的開銷的,但是一般來說這部分開銷不會是主要的。假設上層是順序訪問虛擬內存,這時候讀4K數據,至多發生一次TLB MISS,這個開銷占比不大。如果是隨機訪問,從概率上可以分析出,數據CACHE MISS的次數會比TLB MISS要多很多。而且在這種情況下,作優化,一般也就是把數據連續存放,這時候TLB的CACHE MISS也變小了。目前沒碰到過需要對TLB作優化才能解決的問題。以后用VTUNE的時候,可以專門分析一下。

  除了多層表,還有其他解決方案的,比如用HASH表把所有虛擬內存頁跟物理內存頁的映射記錄下來。HASH的主要問題是數據局部性不好。當順序訪問虛擬內存的時候,查表的時候,卻可能訪問相距很遠的兩個節點。

原文轉自:http://blogread.cn/it/article/3085

国产97人人超碰caoprom_尤物国产在线一区手机播放_精品国产一区二区三_色天使久久综合给合久久97