1. 程式人生 > >【基礎】關於Linux平臺malloc的寫時拷貝(延遲分配)

【基礎】關於Linux平臺malloc的寫時拷貝(延遲分配)

Linux核心定義了“零頁面”(內容全為0的一個物理頁,且實體地址固定),應用層的記憶體分配請求,如棧擴充套件、堆分配、靜態分配等,分配線性地址後,就將頁表項條目指向“零頁面”(指定初始值的情況除外),這樣“零頁面”就被所有程序共享,當向頁面執行寫入操作時,核心就會新分配一個物理頁,實行“寫時拷貝”操作,這樣就實現了物理頁面的延遲分配(如果只有讀沒有寫,則無需另分配物理頁)。

動態記憶體通過glibc庫的malloc函式分配,當現有地址空間不夠時(即malloc維護的空閒連結串列中沒有足夠空間),就呼叫brk/sbrk擴充套件程序空間的相關線性區段,然後將對應頁表項條目指向“零頁面”,寫操作時再分配新頁面。這樣,只要程序空間足夠大,

malloc操作總是成功的——即使申請的記憶體大於系統實體記憶體——失敗會發生在為“寫時拷貝”分配新頁面的時候,當系統可分配記憶體不足時,且有程序要求分配新頁面,核心會Kill該程序,並列印類似“Out of Memory: Killed process xx (xxx).”的資訊。這就是Linux的“

因此不能通過檢測malloc的指標是否為NULL,來判定系統能否支援申請的記憶體大小(即空閒記憶體大於申請記憶體)。

malloc操作示意圖

malloc操作示意圖

malloc分配的這種機制,給應用層判斷動態記憶體是否可分配增加了難度。因為記憶體不足的錯誤被延遲到寫入操作的時候,而在這裡核心沒有提供相關介面給應用層(只是傳送SEGV訊號給臨死的程序)。