虛擬內存按頁劃分,我們可以明確告訴系統:某一個虛擬內存頁需要和實際內存幀相關聯。這樣一來,該內存頁就被換進來了,而且不會被系統換出去。這一行為叫做鎖頁(locking a page)。
一般來講頁的換進換出是透明的,一般程序接觸不到這一層。但是呢,鎖頁可以為我們帶來如下好處:
1、速度:如果你的程序對速度有嚴格的要求,頁錯誤導致頁的換進換出會浪費掉一定的事件。當然為了提高程序速度,你可能還需要提高程序的優先級。
2、隱私安全:沒錯鎖頁可以讓你的程序更加安全。如果你的密碼恰好存放在某一頁上,而這一頁恰好被換出到硬盤的交換區,別人就有更多的機會獲取你的密碼了。
然而你不能鎖太多的頁(這樣就搶了別的程序的資源)
具體細節:
內存鎖只面向虛擬頁,實際內存我們不關心。一個實際內存頁可以對應多個虛擬內存頁,只要有一個虛擬內存頁是鎖著的,實際物理內存頁就不會被換出。
你不可以給一個虛擬內存頁疊加鎖,最多只能有一把鎖。
內存鎖在兩種情況下會被解開:1、進程自行解鎖,2、進程退出,一個進程對應一個虛擬內存,這時候其對應的虛擬內存無效,可以理解虛擬內存頁解鎖了(門都沒了還要鎖干嘛?)。
內存鎖無法被子進程繼承,(注意:現在的UNIX系統中,一旦進行fork操作產生子進程後,子進程和父進程的虛擬內存對應這相同的實際內存幀頁。雖然沒有繼承鎖,但實際享受到了所帶來的好處)
由於會對其他進程帶來影響,所以只有超級用戶才可以鎖頁。但任何進程都可以解鎖頁。
系統會對一個進程可以鎖多少內存加以限制。
即便兩個虛擬內存頁沒有共享內存,但內核仍可能會把兩個虛擬內存頁關聯到同一個內存幀。(事關效率,兩個虛擬內存頁具有完全相同的數據,為何要用兩個不同的內存幀與之對應)如果有一個虛擬內存頁發生數據修改,內核會進行寫時復制(copy-on-write)。
相關函數:
mlock:
int mlock (const void *addr, size_t len) //以addr為起始地址,len為長度的內存塊所在頁鎖起來。(如果頁本來被喚出了,這時候頁會被調入,然後鎖起來) //返回值詳見man手冊
munlock:
int munlock (const void *addr, size_t len) //執行與mlock相反的操作,解鎖
還有其他的一些函數: mlockall和unmallocall。不多介紹了。