堆是程序中用於動態分配變數和資料的記憶體區域。堆的管理對使用者來說是不可見的,因為程式設計師只會使用標準庫提供的輔助函式malloc等來分配任意長度的記憶體區。在kernel和malloc之間的經典介面是brk系統呼叫。堆是可以通過brk系統呼叫收縮和擴充套件的。新近的malloc呼叫使用了brk和匿名對映的組合方法,該方法提供了更好的效能。
堆是一塊連續的記憶體區,擴充套件時是自下向上進行的,堆的位址範圍在mm_struct中的start_brk和brk定義,start_brk定義了堆的起始位址,brk定義了堆的結束位址,start_brk是不會變化的,堆擴充套件或者收縮時會修改brk的值。
brk系統呼叫只有乙個引數,用來指定brk的新的結束位址,新結束位址可以大於mm->brk(老的brk結束位址),也可以小於mm->brk。
236 asmlinkage unsigned long sys_brk(unsigned long brk)
237
268
270 if (find_vma_intersection(mm, oldbrk, newbrk+page_size))
271 goto out;
272
273 /* ok, looks good - let it rip. */
274 if (do_brk(oldbrk, newbrk-oldbrk) != oldbrk)
275 goto out;
276 set_brk:
277 mm->brk = brk;
278 out:
279 retval = mm->brk;
280 up_write(&mm->mmap_sem);
281 return retval;
282 }
244 mm->end_code是**區的結束位址,堆緊鄰**區,所以brk必然要大於mm->end_code
253~255 看起來data和heap區是緊挨著的,二者之和不能大於系統限制,rlimit_data是堆大小限制。
263~267 如果是收縮heap,那麼呼叫do_unmap收縮堆
269~272如果是擴充套件heap,那麼要先檢查堆是否和程序中存在的記憶體對映區重疊,如果二者重疊,那麼就無法擴充套件堆了
273~275 do_brk做堆的實際擴充套件工作。
系統呼叫brk實際上是基於匿名對映的實現,因此大部分用於管理記憶體對映的函式,都可以用於brk。
程序位址空間
這篇文章應該不能說是原創的,這裡的記錄都是我通過閱讀整理來的,並沒有太多的自己的想法。資料 現代作業系統 之所以去了解位址空間也是因為在學習dll的時候看到要將dll對映到程式的位址空間,不甚明了所以去查詢相關的資料。位址空間其實很好理解 當然針對早期的機器 早期的機器是沒有ram,rom,cach...
程序位址空間
kernel筆記 程序位址空間 2013 09 03 09 53 49 分類 linux 下圖是x86 64下linux程序的預設記憶體布局形式 下面逐一分析以上各個位址段的含義。text 段 段,從虛擬記憶體位址00400000開始,使用pmap 可以檢視到,這個位址是固定的 linux pmap...
程序位址空間
程序位址空間 1.可執行檔案 的記憶體對映,稱為 段 2.可執行檔案的已初始化全域性變數的記憶體對映,稱為資料段 3.包含未初始化的全域性變數,也就是bss段的零頁的記憶體對映 4.用於程序使用者控制項棧的零頁的記憶體對映 5.任何記憶體對映檔案 6.任何共享記憶體段 7.任何匿名的記憶體對映,比如...