系統明明有很多內存,卻無法分配一片大塊內存?

發布: 2023-08-01 15:37:08
轉載
1200 人瀏覽過

今日問題:系統明明有很多內存,卻無法分配一片大塊內存?

這是為什麼呢?

這個問題涉及記憶體管理的一個內容-記憶體碎片

#什麼是記憶體碎片?

記憶體碎片在Linux很早的時候就已經出現了,了解早期記憶體碎片產生的歷史,有利於我們對它的理解。

假設現在有一塊32MB大小的內存,一開始作業系統使用了最小的一塊-4MB大小,剩餘的記憶體要留給4個行程使用,如圖(a)所示。

系統明明有很多內存,卻無法分配一片大塊內存?

進程A使用了作業系統往上的10MB內存,進程B使用了進程A往上的6MB內存,進程C使用了進程B往上的8MB內存,如圖(b)所示,:

系統明明有很多內存,卻無法分配一片大塊內存?

#進程D需要5MB內存,所以剩餘的內存不足以裝載進程D,這個內存末位就形成了第一個空洞(記憶體碎片)。假設某個時刻,作業系統需要運行進程D,因為系統中沒有足夠的內存,所以需要選擇一個進程來換出,為進程D騰出足夠的空間。假設作業系統選擇進程B來換出,這樣進程D就裝載到了原來進程B的位址空間裡,於是產生了第二個空洞,如圖(c)所示:

系統明明有很多內存,卻無法分配一片大塊內存?

假設作業系統某個時刻需要執行進程B,也需要選擇一個進程來換出,假設進程A被換出,那麼作業系統中又產生了第三個空洞,如圖(d)所示:

系統明明有很多內存,卻無法分配一片大塊內存?

隨著時間的推移,記憶體空洞會越來越多,記憶體的利用率也隨之下降,這些記憶體空洞就是我們常說的記憶體碎片

系統明明有很多內存,卻無法分配一片大塊內存?

看到這,你已經知道了什麼是記憶體碎片,同時也了解了一種記憶體管理機制-動態分割法。上述舉例其實就是動態分割法,作業系統早期使用動態分割法來管理記憶體。

怎麼解決記憶體碎片化問題?

想法其實很簡單:把多個小塊記憶體拼成一個大塊記憶體

早期使用動態分割法的作業系統,為了解決碎片化問題,就是動態地移動進程,使得進程佔用的空間是連續的,並且所有的空閒空間也是連續,這樣就把多個小內存塊拼起來了。但是缺點也非常明顯,進程的遷移需要花費大量的時間

內碎片與外碎片

#記憶體碎片分兩種:內碎片外部碎片

內碎片:分配給程式的記憶體但未被利用的部分

外碎片:系統無法利用的小記憶體區塊(如上述動態分區法產生的碎片)

如今作業系統使用分頁或分段機制來管理內存,但仍不可避免地會產生一些記憶體碎片。

為了解決內碎片和外碎片問題,Linux引進了兩個東西:夥伴系統slab

夥伴系統用來解決外碎片問題,slab用來解決內碎片問題。

夥伴系統和slab也是記憶體管理中比較核心的內容,有興趣的可以去研究一下。

總結

所以,當系統有很多內存,但無法分配一片大塊記憶體時,就是因為產生了很多內存碎片,導致系統中有很多不連續的小塊內存,表面上看系統空閒內存很多,但實際上都是一些零散的內存。

#

以上是系統明明有很多內存,卻無法分配一片大塊內存?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:嵌入式Linux充电站
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!