題 虛擬內存實際上如何增加內存空間?


據我所知,虛擬內存通過顯示比實際可用內存更多的內存來欺騙程序。

但最終它必須將邏輯地址映射到實際的物理地址。現在如何增加記憶?


68
2018-01-10 07:34


起源


這是舊概念。虛擬內存的最初動機是一種內存管理形式,以提供比物理內存更大的地址空間。但那是因為記憶是低密度而且非常昂貴。如今,使用虛擬內存的主要原因是進程安全性。 - sawdust
“現在它如何增加記憶力?”它沒有。應用程序不知道系統的物理內存,它只知道虛擬內存,這是應用程序抱怨沒有足夠內存的原因,它在談論虛擬內存而不是物理內存 - Ramhound
請記住,虛擬內存系統非常智能。如果n個進程具有相同的只讀頁面,則所有n個進程可以使用相同的一頁物理內存。 - Eric Lippert
不要將虛擬內存視為 嘴硬 任何東西。 內存是存儲和檢索數據的抽像功能。虛擬內存為該抽象提供了一種實現。該抽象的某些部分由RAM支持,而某些部分由磁盤支持是抽象的實現細節。 - Eric Lippert
@HagenvonEitzen不確定磁盤上的“永遠”內存是什麼...除了最初從磁盤讀取的頁面,除非頁面被換出,其內容可能 決不 在磁盤上,對於固定在存儲器中的頁面尤其如此。由於對內核功能至關重要。 - Michael


答案:


它沒有增加 物理 記憶力。它的目的完全是另一回事。它可以做的是提供其他後備存儲,允許程序使用比實際可用內存更多的內存。

虛擬內存用於將進程彼此分離和隔離,並允許將內存訪問轉移到其他位置。

虛擬內存允許系統為每個進程提供與其他進程隔離的自己的內存空間。程序有效地在自己的空間中運行,使它們可以完全訪問整個地址空間,而不必解決可能還需要使用“相同”地址的其他程序。這具有增加可靠性和安全性的副作用,因為過程不容易相互干擾。

根據需要構建應用程序的虛擬內存空間。應用程序看起來(自身)在一個連續的內存塊中,但實際上可能完全分散在物理內存中。

虛擬內存還允許存儲器訪問被捕獲和轉移,這允許我們使用交換文件之類的功能。這意味著我們可以將最近沒有用過的內存部分推送到磁盤並設置一個指針,指示“此內存塊位於文件x的位置y”,然後我們就可以釋放物理內存其他應用程序使用的區域。當應用程序需要該內存時,它可以從磁盤讀回,放置在物理RAM的某個位置(可能與之前的位置不同),並映射回與之前相同的虛擬內存位置。

與使用頁面文件的方式相同,虛擬內存還可以允許操作系統為程序執行有效“懶惰”加載共享庫的操作。當主程序告訴操作系統它想要使用特定庫時,操作系統可以通過檢查庫的需求來節省時間,為應用程序分配虛擬內存區域中的空間,而不是加載整個庫在它中可以推遲從磁盤加載庫的頁面,直到實際需要它們為止。通過這種方式,加載到RAM中的庫的唯一部分是程序實際使用的部分,從不使用的部分永遠不會被加載,因此不會浪費RAM。

使用這些技術,我們可以提高系統的穩定性,並允許更多的進程在狹窄的空間內運行,而不會相互影響。它不會“增加記憶”,而是讓我們更有效地使用我們擁有的東西。

交換文件由虛擬內存系統啟用,但在過去被混淆為 存在 虛擬內存。


116
2018-01-10 07:56



評論不適用於擴展討論;這次談話已經開始了 轉移到聊天。 - Sathya♦


Layman的解釋

當使用該內存時,系統必須將每個虛擬地址映射到物理地址,但是 並非所有內存都在同一時間使用。例如,假設瀏覽器中有20個選項卡,每個選項卡佔用1GB內存。在沒有虛擬內存支持的操作系統中,您需要20GB的RAM才能工作。訣竅是,您不會同時瀏覽所有20個選項卡,因此具有虛擬內存的操作系統將使您能夠使用您的瀏覽器,只需幾GB的RAM,將非活動選項卡交換到磁盤。

更複雜的方面

虛擬內存不專門用於交換。它的主要目的實際上是避免RAM碎片,這是沒有虛擬內存管理的系統上的一個大問題:你可能有1GB的RAM免費,但如果它有10MB的塊,請求100MB的應用程序將無法工作。

隨著時間的推移,虛擬內存發現了更多的用途,特別是隨機文件訪問:如果數據庫被迫按順序讀取文件,那麼許多應用程序(如數據庫)會變得非常慢,如果操作系統讓它們假裝整個文件位於其中,則工作速度會更快(虛擬)內存並根據訪問模式優化磁盤IO和緩存。


21
2018-01-10 12:55



令人遺憾的是,我們生活在一個每個瀏覽器標籤需要1GB內存的世界裡 - tbodt
@tbodt我責怪古埃及人。如果他們只是通過馴服那些討厭的貓而知道他們在做什麼! - Dmitry Grigoryev
@tbodt這有點誇張。打開8個標籤的瀏覽器只需要500MB的內存。 - Random832
@ Random832當然,這是誇大其詞,雖然我不確定誇張與未來之間的界限。我的第一台PC有32 MB的RAM,我可以輕鬆地在Opera中打開8個標籤而不會有明顯的交換。現在它需要500MB,所以再過20年它也可能達到8GB。 - Dmitry Grigoryev


在實際添加更多主內存硬件的意義上,虛擬內存不會增加內存。但它可以 增加可用地址的範圍。因此,可以有一個由代碼段和數據(堆棧和堆)段組成的運行程序,這兩者都可以佔用一系列 虛擬 地址大於 物理 由機器的物理真實存儲空間提供的地址。訣竅在於,任何時刻只有一小部分虛擬地址由物理主內存支持 [但最終所有內容都由磁盤存儲支持]。這是因為現象 參考地點:在任何時刻,只執行程序段的一個或多個小的連續部分中的指令,並且僅對數據段的一個或多個小的連續部分中的數據進行操作。 [當然行為實際上更複雜,但它確實在很大一部分時間內遵循這種模式]


5
2018-01-10 16:14





據我所知,虛擬內存通過顯示比實際可用內存更多的內存來欺騙程序。

虛擬內存的最初動機是一種內存管理形式,以提供比物理內存更大的地址空間。
軟件可以利用CPU的完整地址空間(例如2 ^ 32地址空間),而實際安裝的物理內存只是該數字的一小部分。
大型程序可以在使用虛擬內存的計算機之間移植,而不會產生巨大的(已安裝的)內存需求。
這種虛擬內存的使用是在大型計算機和鐵氧體核心存儲器(這是低密度物理和昂貴的)的那一天。

但最終它必須將邏輯地址映射到實際的物理地址。現在如何增加記憶?

虛擬內存已經從一種技術發展而來,為程序提供更多的地址空間。
虛擬內存是為現代操作系統中的每個進程提供安全性的關鍵組件,因此進程不會干擾其他進程,也不會受到其他進程的影響。
但是多處理(不要與多進程混淆ORS)虛擬內存仍然為系統提供比物理內存更明顯的內存。

為每個創建的進程提供其自己的虛擬地址空間,即其自己的虛擬內存。
實際使用(並映射到虛擬內存)到每個進程的物理內存量是動態的。通常,僅包含執行過程執行的代碼(也稱為文本)和數據頁/段的虛擬存儲器被映射到物理存儲器(也稱為駐留在存儲器中)。

非必要代碼(因為它當前未執行)和數據(因為它沒有被引用/處理)不一定是內存駐留。代碼和/或數據頁/段可以“換出”到後備存儲(例如,HDD或SSD上的交換空間或頁面文件),然後根據需要“交換(後退)”(也稱為“按需”) )。

虛擬內存有助於在眾多進程中有效使用有限物理內存,每個進程都有自己的受保護虛擬地址空間。這些虛擬存儲器的總和通常大於安裝的物理存儲器。
現在,從系統的角度來看,“增加的內存”,而不僅僅是程序的角度。


4
2018-01-10 21:10





虛擬內存增加了程序可以處理的數據量。從軟件的角度來看,我們(通常)並不關心數據的存儲位置。它可以存儲在物理DRAM存儲器中,可以存儲在插入機器的閃存驅動器上,也可以存儲在旋轉盤片上。軟件關心的是,當它要求訪問該數據時,它會成功。

實際上,我們也希望程序能夠快速運行。對於 速度 考慮因素,我們關注數據的位置。我們希望我們最常訪問的數據存儲在允許最快訪問的硬件中。我們的計劃會 喜歡 完全從DRAM運行。但是,我們通常沒有足夠的DRAM來做到這一點。虛擬內存是一種解決方案。

使用虛擬內存,操作系統會“暫存”暫時未使用的數據,並將其存儲在硬盤上。這仍然是可訪問的,只是很慢。如果程序請求硬盤上的數據,則操作系統必須花時間從磁盤讀取數據,然後將其移回DRAM。

理論上,它可以直接從磁盤讀取數據。但是,有理由不這樣做。該計劃不希望必須意識到所有這些並發症。我們可以並且確實編寫了智能地將數據放入磁盤的軟件(稱為緩存)。但是,它需要做很多額外的工作。我們在代碼中做得最快的是:

if data is not in memory
    read data from disk into memory
operate on data

精明的讀者會注意到,即使數據在內存中,我們也必須有一個條件來檢查它是否存在。這比直接在內存中運行慢得多!

虛擬內存通過在CPU上執行硬件檢查來解決此問題。 CPU可以非常快速地執行此虛擬內存操作,因為它可以專用硬件。單獨使用軟件進行此操作的任何嘗試都必須使用CPU的通用部件,這些部件自然比專用晶體管慢。

這導致了為什麼我們總是將數據分頁回內存,而不是僅僅從磁盤讀取數據並將其留在內存中。我們將內存分解為“頁面”,每個頁面都標記為存在或不存在於內存中。操作系統以便於CPU直接使用的格式維護該表。只要程序訪問存在的數據,CPU上的硬件就可以直接訪問DRAM中的數據。當數據不存在時,發出“頁面錯誤”,告訴操作系統將該頁面從磁盤加載到某個物理頁面的內存,並更新表格以將CPU指向這個新的物理頁面。

整個問題的關鍵是盡量減少其使用。實際上,我們發現操作系統非常擅長選擇要保留在內存中的數據以及要將哪些數據分頁到磁盤,因此絕大多數內存訪問都不會導致頁面錯誤。


3
2018-01-10 20:01





它通過使地圖條目臨時來實現。

當程序訪問邏輯地址時,CPU在映射中查找相應的物理地址。如果找到,則內存訪問按預期進行;如果沒有找到,則必須分配物理地址,並從其他存儲器加載內容 - “交換空間”。如果每個物理地址已經分配給某個邏輯地址,則必須“換出”某些邏輯地址(將其內容保存回交換空間)以使物理地址可用。

分配的最大內存是交換空間的大小,可以比安裝的內存大得多。將交換空間視為“真實”內存,將RAM視為交換空間的高速緩存可能會有所幫助。

(這遠非徹底的描述,它旨在回答當前的問題而不涉及相關但不必要的細節。)


2
2018-01-11 20:16





基本概念依賴於這樣一個事實:現代CPU可以管理轉換錶,跟踪“已經分配了某個進程使用的地址範圍,以及哪些物理地址(想想內存總線上的A00..Axx行),如果有的話,目前用於實際存儲數據。“IF ANY”因為“根本沒有”是可能的和可接受的狀態:在這種情況下,將在硬件級別上引發錯誤條件(所謂的“頁面錯誤”) - 此錯誤將觸發操作系統級處理程序,例如可以將已寫入交換文件的內存內容加載回物理內存中的任何空閒位置(如果是讀取)或找到放置內容的實際位置(在寫入的情況),更新前面提到的轉換錶,然後只有那麼手控制回到試圖訪問該存儲器的進程..並且這將不是所發生的事情的明智之處。


1
2018-01-10 10:48





虛擬內存:

1)允許將大的虛擬地址空間映射到較少量的物理內存,將多餘的“交換”到磁盤或SSD,或者前瞻性地映射到NVRAM和其他設備。

2)允許更大的虛擬地址空間(例如64位)映射到更小的物理地址空間(例如32或64位)

3)允許較小的虛擬地址空間(例如32位)映射到較大的物理地址空間(例如40位),從而允許較舊的應用程序利用更多的物理DRAM。

4)允許在物理地址空間中分段和非連續的物理存儲器在虛擬地址空間中呈現為連續的。

5)允許進程給出它們自己的虛擬地址空間,因此彼此隔離。

6)允許碰巧共享相同數據值的不同虛擬地址分配單個物理頁面。

這可能發生在單個進程或操作系統中 - 大多數BSD UNIX派生的操作系統都有一個零的只讀頁面,可以映射到任何零填充的虛擬頁面,通常是COW(寫入時復制 - 只讀零,寫入被困)並且頁面未共享並且可寫入)。

它可能發生在進程之間 - 例如UNIX fork()創建以COW方式共享幾乎所有虛擬內存的子進程。

它可能發生在操作系統之間 - 例如虛擬機主機上的來賓操作系統可以具有重複數據刪除,共享COW等頁面。(最近的一些安全攻擊利用了這一點。)

7)虛擬內存可以允許部分虛擬地址空間映射到文件,或映射到其他處理器上的內存,無論是在同一個多處理器系統中,還是在Internet上。


0
2018-01-17 05:26