Share via


記憶體保護

屬於進程的記憶體會受到其私人虛擬位址空間隱含保護。 此外,Windows 會使用虛擬記憶體硬體來提供記憶體保護。 此保護的實作會隨著處理器而有所不同,例如,進程位址空間中的字碼頁可以標示為唯讀,並受到使用者模式執行緒修改的保護。

如需屬性的完整清單,請參閱 記憶體保護常數

寫入時禁止複製

寫入禁止複製是一項優化,可讓多個進程對應其虛擬位址空間,使其共用實體頁面,直到其中一個進程修改頁面為止。 這是稱為 延遲評估的技術的一部分,可讓系統在絕對必要之前不執行作業來節省實體記憶體和時間。

例如,假設兩個進程會將頁面從相同的 DLL 載入到其虛擬記憶體空間中。 這些虛擬記憶體分頁會對應至這兩個進程的相同實體記憶體分頁。 只要這兩個進程都不會寫入這些頁面,就可以對應到和共用相同的實體頁面,如下圖所示。

對應至相同實體記憶體的進程 1 和 2 頁方塊和箭號

如果 Process 1 寫入其中一個頁面,實體頁面的內容會複製到另一個實體頁面,並更新進程 1 的虛擬記憶體對應。 這兩個進程現在在實體記憶體中都有自己的頁面實例。 因此,無法讓一個進程寫入共用實體頁面,而另一個進程查看變更。

進程和實體記憶體重新對應的方塊和箭號

載入應用程式和 DLL

載入相同 Windows 型應用程式的多個實例時,每個實例都會在自己的受保護虛擬位址空間中執行。 不過,其實例會處理 (hInstance) 通常具有相同的值。 這個值代表應用程式在其虛擬位址空間中的基底位址。 如果每個實例都可以載入其預設基底位址,則可以使用寫入禁止複製,對應至其他實例並共用相同的實體頁面。 系統允許這些實例共用相同的實體頁面,直到其中一個實例修改頁面為止。 如果基於某些原因,其中一個實例無法載入所需的基底位址,則會接收自己的實體頁面。

DLL 會以預設基底位址建立。 使用 DLL 的每個進程都會嘗試在 DLL 的預設虛擬位址處,在其自己的位址空間內載入 DLL。 如果多個應用程式可以在預設虛擬位址載入 DLL,他們可以共用 DLL 的相同實體頁面。 如果因為某些原因,進程無法在預設位址載入 DLL,它會將 DLL 載入其他地方。 寫入時禁止複製會強制將部分 DLL 頁面複製到此程式的不同實體頁面,因為跳躍指令的修正是在 DLL 的頁面內寫入,因此此程式會不同。 如果程式碼區段包含資料區段的許多參考,這可能會導致整個程式碼區段複製到新的實體頁面。