一篇解決Linux內核內存布局與堆管理
內核內存布局
64位Linux一般使用48位來表示虛擬地址空間,43位表示物理地址, 通過命令:cat /proc/cpuinfo。

cat /proc/meminfo

ARM64架構處理器采用48位物理尋址機制,最大可尋找256TB的物理地址空間。對于目前應用完全足夠,不需要擴展到64位的物理尋址。虛擬地址也同樣最大支持48位尋址,所以 在處理器架構設計上,把虛擬地址空間劃分為兩個空間,每個空間最大支持256TB,linux內核在大多數(shù)體系結構上都把兩個地址劃分為:用戶空間和內核空間。 用戶空間:0x0000_0000_0000_0000至0x0000_ffff_ffff_ffff。 內核空間:0xffff_0000_0000_0000至0xffff_ffff_ffff_ffff。
【文章福利】小編推薦自己的Linux內核技術交流群:【891587639】整理了一些個人覺得比較好的學習書籍、視頻資料共享在群文件里面,有需要的可以自行添加哦?。。。ê曨l教程、電子書、實戰(zhàn)項目及代碼)??


內存布局
QEMU平臺,可以打印ARM64架構linux內核內存分布情況。

堆管理
堆是進程中主要用于動態(tài)分配變量和數(shù)據 的內存區(qū)域,堆的管理對應程序員不是直接可見的。因為它依賴標準庫提供的各個輔助函數(shù)(其 中最重要的是malloc)來分配任意長度的內存區(qū)。 malloc和內核之間的經典接口是brk系統(tǒng)調用,負責擴展/收縮堆。 堆是一個連續(xù)的內存區(qū)域,在擴展時自下至上增長。其中mm_struct結構,包含堆在虛擬地 址空間中的起始和當前結束地址(start_brk和brk)。
sys_brk流程

brk機制基于匿名映射實現(xiàn),以減少內部的開銷。在檢查過用于brk的值的新地址未超出堆的限制之后,sys_brk第一個重要的操作是將請求的地址按頁長對齊。 brk()用于用戶進程想內核申請空間,用于擴展用戶堆??臻g,或者回收用戶堆棧空間。 malloc()為小空間申請,brk()為大空間申請。do_brk()用于增長動態(tài)分配區(qū)。do_munmap()釋放動態(tài)分配區(qū)。
do_brk()源碼分析
大內核鎖BKL
遞歸鎖:嵌套上鎖解鎖。
自動釋放特性。
本質上自旋鎖,不同在于自旋鎖不可以遞歸獲取鎖(會導致死鎖),大內核鎖可以遞歸獲取鎖,保護整個內核。保持鎖的時間太長,嚴重影響系統(tǒng)性能和可伸縮性,因而被淘汰。 【注意】 原子操作對整數(shù)操作,自旋鎖和信號量應用比較廣泛。當臨界區(qū)小應該選擇自旋鎖,反之應該信號量。
per-CPU計數(shù)器
引入目的是加速SMP系統(tǒng)上計數(shù)器操作。 基本原理: 計數(shù)器的準確值存儲在內存中的某一個地址,準確值所在內存位置之后是一個數(shù)組,每個數(shù)組想對應于系統(tǒng)中的一個CPU。 Linux系統(tǒng)尤其是針對SMP或者NUMA架構的多CPU系統(tǒng)的時候,主要描述每個CPU私有數(shù)據時,系統(tǒng)提供該機制per-cpu。 三種CPU模式:x86 x64 ia64 X86表示基于X86指令安裝模式; x64表示64位系統(tǒng)程序; ia64主要用于企業(yè)級服務器,inter安騰架構基于a64處理器架構的服務器,64位運算能力、尋址空間,數(shù)據處理能力方面突破性提高。
總結
本文介紹了內核的內存布局,分布情況,堆管理,malloc與brk區(qū)別,大內核鎖,per-CPU計數(shù)器等。
