天天看點

為什麼不能配置設定一塊全局性的使用者模式記憶體空間?

有那麼一個偶然時刻,有朋友問起我,有沒有一種方法,可以保留一塊使用者模式下的全局性的記憶體空間。換句話說,他們是希望配置設定一塊全系統裡所有程序都可以通路的一塊公用記憶體塊,這裡,所有的程序不僅包括現在正在運作的,也包含了将來即将運作的那些程序。

他們這樣問的原因大抵在于,他們希望将一些使用者模式的記憶體資料映射到系統的每一個程序中,并且不想自己設計一種共享記憶體機制來實作這個場景。

顯然,這不太可行。為什麼顯然不行。

好吧,我們這樣去思考:如果這種方案可行,會發生什麼?”如果它可行,則會發生什麼”這個思維方式是一種用來判斷一種理論是否可能為真的有效邏輯方法。

如果我們真的允許開發者配置設定一款全局記憶體空間,會帶來什麼結果?

首先,我們并不能確定當你執行記憶體配置設定的時候,系統一定就有可用的記憶體供你配置設定。

假設,有一個程式在嘗試耗盡使用者模式位址空間(它可以通過在一個無限循環中調用VirtualAlloc(MEM_RESERVE)函數來實作,因為沒有實際的記憶體被送出,是以,系統不需要實際的2G真實記憶體)

當執行這個一個程式的時候,系統将沒有任何可用的位址空間可供配置設定,直到這個程式終止運作。是以,即使這種方案在技術層面是可行的,但是也不是十分可靠。你的程式需要面對這種系統可能沒有可用記憶體配置設定的情景。無論如何,你都需要在程式中編寫錯誤處理代碼,是以這種方案并沒有實際減少對應的工作量。

第二個原因是,如果這種方案可行,則系統應該會提供一個類似于GlobalVirtualAlloc這樣的API函數。那麼,很好,我可以寫一個簡單的程式,在一個循環中不停地調用這個函數,這就可以輕松地耗盡全局虛拟位址空間,并且,更要命的是,我将會以一個非管理者權限運作這個程式。會發生什麼呢?

我的一個簡單的程式,直接會導緻它吃掉所有的全局虛拟位址空間,相應的,這也會減少其他的以管理者權限運作的程式可以配置設定的位址空間容量。如果系統上運作的程式不多,我的程式可能會通過這種方式占用相當多的位址空間,這反過來會導緻這些管理者程式的可用位址空間相應減少。是以,我可以使這些程式更快地耗盡位址空間,進而導緻過早失敗(DOS, 拒絕服務)。

的确,你可以設計為,全局位址空間僅對管理者程式可用,但這對懶惰的程式員沒有幫助,因為該程式在以非管理者身份運作時無法運作——無論如何你都必須編寫錯誤處理代碼。

或者,你也可以設計為,全局位址空間僅适用于具有相同安全令牌的同一會話中的使用者程式,但同樣,如果全局位址配置設定失敗,你仍然必須編寫錯誤處理代碼,看起來,這沒有為自己節省任何工作。

時機成熟時,你可以使用VirtualAlloc并傳遞一個首選位址來嘗試擷取該位址處的記憶體;如果失敗,則會執行你已經編寫的錯誤處理代碼。

今天文章的中心思想是:系統中的每一個程序,都擁有它們自己的位址空間,且它們各自對該位址空間的任何操作不會影響到其他程序。

當然,一個例外情況是,一個程序可以授予使用者PROCESS_VM_OPERATION權限,該權限授予該使用者處理該程序的位址空間的權限。 但是對該程序位址空間的更改不會影響其他程序的位址空間。

總結

最後