首頁 區(qū)塊鏈 > 正文

系統(tǒng)內(nèi)存管理:虛擬內(nèi)存、內(nèi)存分段與分頁、頁表緩存TLB以及Linux內(nèi)存管理

虛擬內(nèi)存

虛擬內(nèi)存是一種操作系統(tǒng)提供的機制,用于將每個進(jìn)程分配的獨立的虛擬地址空間映射到實際的物理內(nèi)存地址空間上。通過使用虛擬內(nèi)存,操作系統(tǒng)可以有效地解決多個應(yīng)用程序直接操作物理內(nèi)存可能引發(fā)的沖突問題。

在使用虛擬內(nèi)存的情況下,每個進(jìn)程都有自己的獨立的虛擬地址空間,它們不能直接訪問物理內(nèi)存地址。當(dāng)程序訪問虛擬內(nèi)存地址時,操作系統(tǒng)會進(jìn)行地址轉(zhuǎn)換,將虛擬地址映射到物理地址上,這樣不同的進(jìn)程運行時,寫入的是不同的物理地址,避免了互相覆蓋指針的問題。

虛擬內(nèi)存的使用使得每個進(jìn)程都可以擁有相同的虛擬地址空間,而不用擔(dān)心與其他進(jìn)程的地址沖突。操作系統(tǒng)負(fù)責(zé)管理虛擬地址和物理地址之間的映射關(guān)系,并在需要時進(jìn)行地址轉(zhuǎn)換。這樣,進(jìn)程可以以一種透明的方式訪問內(nèi)存,無需關(guān)心內(nèi)存的實際物理位置。


(資料圖片僅供參考)

通過虛擬內(nèi)存機制,操作系統(tǒng)能夠更好地管理系統(tǒng)內(nèi)存資源,提供更高的安全性和穩(wěn)定性。它可以為每個進(jìn)程提供獨立的地址空間,保護(hù)進(jìn)程間的數(shù)據(jù)隔離,同時也可以有效地利用物理內(nèi)存,將不常用的數(shù)據(jù)交換到磁盤上(交換區(qū)),以提供更大的可用內(nèi)存空間。

內(nèi)存分段

在分段機制下,虛擬地址由兩部分組成:段選擇子和段內(nèi)偏移量。段選擇子是一個索引,用于指定要訪問的段的起始地址和長度。段內(nèi)偏移量則表示在該段內(nèi)的具體位置。

操作系統(tǒng)會維護(hù)一個段表,其中包含了每個段的起始地址和長度信息。當(dāng)程序訪問一個虛擬地址時,操作系統(tǒng)會通過段選擇子從段表中找到對應(yīng)的段描述符,然后根據(jù)段描述符中的信息計算出物理地址。

具體的映射過程如下:

程序訪問虛擬地址,通過段選擇子找到對應(yīng)的段描述符。根據(jù)段描述符中的基址和長度信息,計算出段的起始物理地址。將段的起始物理地址與段內(nèi)偏移量相加,得到最終的物理地址。

不過,需要注意的是,分段機制可能會導(dǎo)致內(nèi)存碎片的問題,因為不同段的大小可能不同,導(dǎo)致一些碎片化的空間無法被利用。當(dāng)不夠內(nèi)存分配的時候,會選擇使用內(nèi)存交換,先把一塊正在使用的內(nèi)存移到磁盤中,然后再移回來把中間留的內(nèi)存縫隙全用上,雖然解決了內(nèi)存碎片的問題,但是這個交換操作很慢,效率低,看下圖示:

虛擬內(nèi)存、分段和內(nèi)存交換似乎解決了同時運行多個程序的問題,但仍存在性能瓶頸。由于硬盤訪問速度較慢,每次內(nèi)存交換都需要將大段連續(xù)的內(nèi)存數(shù)據(jù)寫入硬盤。因此,如果交換的是占用大量內(nèi)存空間的程序,整個系統(tǒng)會變得卡頓。

為了解決內(nèi)存分段的碎片和提高內(nèi)存交換效率,引入了內(nèi)存分頁機制。

內(nèi)存分頁

內(nèi)存分頁是將整個虛擬和物理內(nèi)存空間劃分為固定大小的連續(xù)內(nèi)存塊,稱為頁(Page)。在Linux下,每一頁的大小通常為4KB。虛擬地址與物理地址之間通過頁表進(jìn)行映射,頁表存儲在CPU的內(nèi)存管理單元(MMU)中,從而CPU可以直接通過MMU找到實際訪問的物理內(nèi)存地址。

虛擬地址與物理地址之間通過頁表來映射,如下圖:

由于內(nèi)存空間事先劃分為固定大小的頁,不會像分段機制那樣產(chǎn)生碎片。當(dāng)釋放內(nèi)存時,以頁為單位進(jìn)行釋放,避免了無法利用的小內(nèi)存塊。

如果內(nèi)存空間不足,操作系統(tǒng)會將其他正在運行的進(jìn)程中的"最近未使用"的內(nèi)存頁面暫時存儲到硬盤上,稱為換出(Swap Out)。當(dāng)需要時,再將頁面加載回內(nèi)存,稱為換入(Swap In)。因此,每次寫入硬盤的是少量的一頁或幾頁,不會花費太多時間,從而提高了內(nèi)存交換的效率。

簡單分頁

簡單分頁存在空間上的缺陷。在操作系統(tǒng)可以同時運行大量進(jìn)程的情況下,頁表會變得非常龐大。在32位環(huán)境下,虛擬地址空間為4GB,假設(shè)頁的大小為4KB,就需要大約100萬個頁。每個頁表項需要4字節(jié)來存儲,所以整個4GB空間的映射需要4MB的內(nèi)存來存儲頁表。

盡管4MB的頁表看起來并不算太大,但要注意每個進(jìn)程都有自己的虛擬地址空間,也就是說每個進(jìn)程都有自己的頁表。如果有100個進(jìn)程,就需要400MB的內(nèi)存來存儲頁表,這對于內(nèi)存來說是相當(dāng)大的開銷,更不用說64位環(huán)境下了。

多級頁表

要解決上述問題,我們可以采用一種叫做多級頁表(Multi-Level Page Table)的解決方案。在之前我們已經(jīng)了解到,在32位環(huán)境下,頁大小為4KB的情況下,一個進(jìn)程的頁表需要存儲100多萬個頁表項,每個項占用4字節(jié)的空間,因此一個頁表需要4MB的內(nèi)存空間。

為了節(jié)省內(nèi)存空間,我們可以將單級頁表進(jìn)行分頁,將一個頁表(一級頁表)分為1024個頁表(二級頁表),每個二級頁表包含1024個頁表項,形成二級分頁結(jié)構(gòu)。這樣一級頁表覆蓋整個4GB的虛擬地址空間,而對于未使用的頁表項,不會創(chuàng)建對應(yīng)的二級頁表,只在需要時才創(chuàng)建。如下圖所示:

換個角度來看,大多數(shù)程序未使用到整個4GB的虛擬地址空間,因此部分頁表項是空的,沒有分配實際的內(nèi)存空間。在物理內(nèi)存緊張的情況下,操作系統(tǒng)會將最近一段時間未訪問的頁表換出到硬盤,從而釋放物理內(nèi)存。使用二級分頁,一級頁表只需要覆蓋整個4GB的虛擬地址空間,而未使用的頁表項不需要創(chuàng)建對應(yīng)的二級頁表。假設(shè)只有20%的一級頁表項被使用,那么頁表占用的內(nèi)存空間只有0.804MB,相比于單級頁表的4MB,內(nèi)存節(jié)約非常巨大。

為什么不分級的頁表無法實現(xiàn)這樣的內(nèi)存節(jié)約呢?從頁表的性質(zhì)來看,頁表保存在內(nèi)存中,其主要作用是將虛擬地址翻譯為物理地址。如果在頁表中找不到對應(yīng)的頁表項,計算機系統(tǒng)將無法正常工作。因此,頁表必須覆蓋整個虛擬地址空間。而不分級的頁表需要100多萬個頁表項進(jìn)行映射,而二級分頁只需要1024個頁表項(一級頁表覆蓋整個虛擬地址空間,二級頁表在需要時創(chuàng)建)。

頁表緩存TLB(Translation Lookaside Buffer)

TLB(Translation Lookaside Buffer)是一個位于CPU芯片中的緩存,用于存儲程序中最常訪問的頁表項,以加快虛擬地址到物理地址的轉(zhuǎn)換速度。多級頁表雖然解決了空間上的問題,但是增加了轉(zhuǎn)換的工序,導(dǎo)致時間上的開銷。然而,由于程序的局部性原理,程序執(zhí)行期間通常僅限于某一部分,訪問的存儲空間也局限于某個內(nèi)存區(qū)域。因此,通過將最常訪問的頁表項存儲到TLB這個硬件緩存中,可以更快地進(jìn)行地址轉(zhuǎn)換。

在CPU芯片中,內(nèi)存管理單元(Memory Management Unit)芯片負(fù)責(zé)處理地址轉(zhuǎn)換和TLB的訪問與交互。當(dāng)CPU進(jìn)行尋址時,首先會查找TLB,如果找到了對應(yīng)的頁表項,就可以直接進(jìn)行物理地址的訪問,避免了繼續(xù)查找常規(guī)頁表的開銷。

由于TLB中存儲的是程序最常訪問的幾個頁表項,所以TLB的命中率通常是很高的。這是因為程序執(zhí)行過程中,訪問的頁表項相對固定。通過利用TLB,可以大大提高地址轉(zhuǎn)換的速度,加快程序的執(zhí)行效率。

Linux內(nèi)存管理

Linux內(nèi)存管理涉及邏輯地址和線性地址的轉(zhuǎn)換。邏輯地址是程序使用的地址,而線性地址是通過段式內(nèi)存管理映射的地址,也稱為虛擬地址。

Linux的虛擬地址空間分為內(nèi)核空間和用戶空間兩部分。32位系統(tǒng)中,內(nèi)核空間占用1G,剩下的3G是用戶空間;64位系統(tǒng)中,內(nèi)核空間和用戶空間都是128T,分別占據(jù)內(nèi)存空間的最高和最低處。如下所示:

進(jìn)程在用戶態(tài)時只能訪問用戶空間內(nèi)存,進(jìn)入內(nèi)核態(tài)后才能訪問內(nèi)核空間內(nèi)存。雖然每個進(jìn)程都有獨立的虛擬內(nèi)存,但虛擬內(nèi)存中的內(nèi)核地址關(guān)聯(lián)的是相同的物理內(nèi)存,這樣進(jìn)程切換到內(nèi)核態(tài)后就可以方便地訪問內(nèi)核空間內(nèi)存。

總結(jié)

虛擬內(nèi)存是操作系統(tǒng)提供的一種機制,通過將每個進(jìn)程分配的獨立的虛擬地址空間映射到實際的物理內(nèi)存地址空間上,解決了多個應(yīng)用程序直接操作物理內(nèi)存可能引發(fā)的沖突問題。虛擬內(nèi)存的使用使得每個進(jìn)程都可以擁有相同的虛擬地址空間,而不用擔(dān)心與其他進(jìn)程的地址沖突。通過虛擬內(nèi)存機制,操作系統(tǒng)能夠更好地管理系統(tǒng)內(nèi)存資源,提供更高的安全性和穩(wěn)定性。虛擬內(nèi)存的實現(xiàn)方式有分段和分頁,其中分頁機制更為常用,采用多級頁表的方式節(jié)約了內(nèi)存空間。頁表緩存TLB能夠加快虛擬地址到物理地址的轉(zhuǎn)換速度。Linux的內(nèi)存管理涉及邏輯地址和線性地址的轉(zhuǎn)換,將虛擬地址空間分為內(nèi)核空間和用戶空間,方便進(jìn)程訪問內(nèi)核空間內(nèi)存。

關(guān)鍵詞:

最近更新

關(guān)于本站 管理團(tuán)隊 版權(quán)申明 網(wǎng)站地圖 聯(lián)系合作 招聘信息

Copyright © 2005-2023 創(chuàng)投網(wǎng) - 670818.com All rights reserved
聯(lián)系我們:39 60 29 14 2@qq.com
皖I(lǐng)CP備2022009963號-3