記憶體碎片的由來

2021-09-03 07:06:15 字數 1642 閱讀 8500

經常看別人部落格說到「記憶體碎片」這個概念,而且很多程式設計技巧書也經常提到頻繁地呼叫記憶體分配函式會導致越來越多的記憶體碎片產生,降低記憶體的利用率。那麼這個「記憶體碎片」究竟是怎麼產生的呢?答案可能要從「作業系統」中查詢了。

在翻閱了一些《作業系統》的書之後,對於這個概念有了更清晰的理解,下面進行總結:

當我們執行乙個程式時,處理器要生成乙個程序,並把程式載入記憶體。那麼記憶體是如何分割槽的呢?是分成固定大小的一塊一塊麼?的確存在這種設計方案,那麼我們看看針對這種情況,碎片會出現在**?假設我們的乙個分割槽是8m,我們的程序大小是3m,那麼當我們的程序裝入分割槽後,分割槽裡面剩餘的5m我們並沒有用到,而且由於這個分割槽其他程序也不能同時使用,所以這5m就被浪費了,這種浪費其實就是「碎片」,由於這種碎片出現在分區內,一般我們稱它為「內部碎片」。那麼我們是否可以使用大小不同的分割槽呢?比如分割槽大小從小到大排列 2m、4m、6m、8m、10m。這種方案會緩解這個問題,但並不能完全解決。

那麼是否有其他方案可供我們選擇呢?我們是不是可以嘗試動態分割槽,我們的程序有多大,分割槽大小就為多大。這種方案當然也存在,假設我們先裝入乙個程序1:20m,然後再裝入程序2:14m,再裝入乙個程序3:18m。接下來程序2執行結束被換出,接著執行乙個程序4:8m。現在加入我們要繼續裝入乙個大小為9m的程序的話,會發現已經沒有空閒間隙給我們。可實際上記憶體還留有10m的空間,只是它們並沒有連續。所以我們現在遇到了空間還夠卻無法裝入程序的窘境。那些空隙我們就可以稱為「外部碎片」,也就是說採用動態分割槽的方案會產生「外部碎片」。

那麼有方法可以克服外部碎片的技術麼?「壓縮」聽名字你大概能猜出來,壓縮其實就是將那邊不連續儲存的程序壓到一起,這樣那些中間的空隙也就是外部碎片就消失了。但是壓縮是十分耗時間的,同時壓縮之後程序的位置也發生了改變,所以我們要求如果支援壓縮操作的話,則程序必須得是可動態重定位的(只有當我們訪問到某個變數時,才去計算絕對位址)。也就是說裝載程式時,程式內訪問記憶體的方式不能是絕對定址,而是相對定位的,比如說我們的變數只儲存相對位址,等到程式實際執行時獲得實際位址時,變數再針對這個相對位址得到實際位址。

缺點:當我們多個程式共享記憶體時,無法確定哪塊區域一定是留給你用的。

由於記憶體壓縮十分耗時,,因而作業系統需要巧妙地把程序分配到記憶體中,以便蓋住那些「空隙」。一般來說有三種放置演算法:

1.最佳適配:找到最接近程序大小的空隙

2.首次適配:從頭開始找第乙個可以放下程序的空隙

3.下次適配:從上次找到的空隙往後找可以放下程序的空隙

首次適配一般的結果是最好最優的,下次適配會使得儲存空間末尾的最大空閒儲存塊很快**為小碎塊,因此使用下次匹配可能會使得更多次的壓縮。最佳適配儘管每次都能找到最匹配空間的空隙,但效能太差,類似順序遍歷查詢最大值最小值的演算法是o(n)的效率一樣,平均要掃瞄整個記憶體塊。

大小不等的固定分割槽和大小可變的分割槽技術在記憶體上的使用都是低效的,前者會產生內部碎片,後者會產生外部碎片。如果我們採用分頁技術,將程序分為固定大小的塊,將記憶體也分為固定大小的塊。那麼程序的一塊可以稱為「頁」,記憶體中的一塊可以稱為可以稱為「頁框」。一般來說每一頁是4k的樣子,使用分頁技術我們每個程序浪費的空間最多就是程序最後一頁的一小部分。很小的內部碎片,但是沒有外部碎片。

Linux高階記憶體的由來

抱著拿來主義,自己挑選了部分,以下內容摘自網路。linux核心位址空間劃分 通常32位linux核心位址空間劃分0 3g為使用者空間,3 4g為核心空間。注意這裡是32位核心位址空間劃分,64位核心位址空間劃分是不同的。linux核心高階記憶體的由來 當核心模組 或執行緒訪問記憶體時,中的記憶體位址...

記憶體管理,問題由來

為什麼需要記憶體管理?我覺得最根本的問題在於多程序。如果不進行記憶體管理,兩個程式幾乎是沒可能同時在記憶體執行的。在只有記憶體的物理模型且沒有特殊硬體管理的情況下,乙個程式的內容會被另乙個程式修改,直接崩潰。如何管理記憶體,才能達到多執行緒?1 無記憶體抽象 需要特殊硬體 記憶體鍵 早期ibm,存在...

記憶體管理的內碎片和外碎片

在記憶體管理中,內零頭 和 外零頭 個指的是什麼?在固定式分割槽分配 可變式分割槽分配 頁式虛擬儲存系統 段式虛擬儲存系統中,各會存在何種零頭?為什麼?解答 在儲存管理中,內零頭是指分配給作業的儲存空間中未被利用的部分,外零頭是指系統中無法利用的小儲存塊。在固定式分割槽分配中,為將乙個使用者作業裝入...