記憶體碎片產生原因及解決辦法

2021-08-28 13:28:10 字數 1983 閱讀 4792

記憶體碎片通常分為內部碎片和外部碎片:

1. 內部碎片是由於採用固定大小的記憶體分割槽,當乙個程序不能完全使用分給它的固定記憶體區域時就產生了內部碎片,通常內部碎片難以完全避免;

2. 外部碎片是由於某些未分配的連續記憶體區域太小,以至於不能滿足任意程序的記憶體分配請求,從而不能被程序利用的記憶體區域。

現在普遍採用的段頁式記憶體分配方式就是將程序的記憶體區域分為不同的段,然後將每一段由多個固定大小的頁組成。通過頁表機制,使段內的頁可以不必連續處於同一記憶體區域,從而減少了外部碎片,然而同一頁內仍然可能存在少量的內部碎片,只是一頁的記憶體空間本就較小,從而使可能存在的內部碎片也較少。

解決辦法:

首先,使用最原始的標記分配方法,系統需要維護乙個簡單的記憶體資訊表:

當程式申請乙個長度為3的記憶體空間後:

當程式再申請乙個長度為2,以及長度為4的記憶體空間後:

此時,只剩1個可用空間。如果這時程式再來申請長度大於1的空間,就申請不了,也就是記憶體不夠。

現在,釋放掉id=2的空間:

我們發現,現在可用記憶體空間為3,但是,這3個空閒空間,並不是連續的。所以,如果程式現在申請長度為3的記憶體空間,同樣會申請不了,會出現記憶體不夠。業界把這種情況,稱之為【記憶體碎片】。

明明剩餘有3個空間,卻申請不了3個記憶體空間,這***扯蛋?

於是,工程師們,發明了基於頁面的記憶體管理方式:

首先,把物理記憶體,按照某種尺寸,進行平均分割。比如我現在以2個記憶體單位,來分割記憶體,也就是每兩個連續的記憶體空間,組成乙個記憶體頁:

接著,系統同樣需要維護乙個記憶體資訊表:

現在,程式申請長度為3的記憶體空間,不過由於現在申請的最小單位為頁面,而乙個頁面的長度為2,因此現在需要申請2個頁面,也就是4個記憶體空間。你看,這就浪費了1個記憶體空間。

接著,程式再申請長度為1,長度為2的空間:

釋放掉id=2,記憶體頁id為3的那條記憶體空間資訊:

現在,就出現了之前的情況:目前一共有4個記憶體空間,但是不連續。不過,因為現在是分頁管理機制,因此,現在仍然可以繼續申請長度為4的記憶體空間:

這種方案是不是爽得多?沒有碎片,能夠盡量地全部用完空間。但仔細想想,這種優勢背後,也是需要付出大量代價的。

前面那種記憶體分配方式,雖然容易出現碎片,並且記憶體空間的利用率低,但是使用效能高,程式能直接從記憶體資訊表獲取記憶體位址,接著就可以直接按照位址來使用記憶體空間了。

但下面這種分頁的方式,程式需要記錄的是記憶體頁id,每次使用時,需要從記憶體頁id翻譯成實際記憶體位址,多了一次轉換。而且這種模式,會浪費一些記憶體,比如上面申請3個記憶體空間,實際分配了2個頁面共4個記憶體空間,浪費了1個記憶體空間。

記憶體碎片產生原因及終極解決辦法

記憶體碎片通常分為內部碎片和外部碎片 內部碎片是由於採用固定大小的記憶體分割槽,當乙個程序不能完全使用分給它的固定記憶體區域時就產生了內部碎片,通常內部碎片難以完全避免 外部碎片是由於某些未分配的連續記憶體區域太小,以至於不能滿足任意程序的記憶體分配請求,從而不能被程序利用的記憶體區域。現在普遍採用...

作業系統 記憶體碎片產生原因及終極解決辦法

1.內部碎片是由於採用固定大小的記憶體分割槽,當乙個程序不能完全使用分給它的固定記憶體區域時就產生了內部碎片,通常內部碎片難以完全避免 2.外部碎片是由於某些未分配的連續記憶體區域太小,以至於不能滿足任意程序的記憶體分配請求,從而不能被程序利用的記憶體區域。現在普遍採用的段頁式記憶體分配方式就是將程...

野指標產生原因及解決辦法

原因 指標變數宣告時沒有被初始化。解決辦法 指標宣告時初始化,可以是具體的位址值,也可讓它指向null。原因 指標 p 被 free 或者 delete 之後,沒有置為 null。解決辦法 指標指向的記憶體空間被釋放後指標應該指向null。原因 指標操作超越了變數的作用範圍。解決辦法 在變數的作用域...