Linux的內存管理涉及到的內容很是龐雜,並且與內核的方方面面耦合在一塊兒,想要理解透徹很是困難。html
在開始學習以前進行了一些準備工做《如何展開Linux Memory Management學習?》,linux
遂決定以以下資料做爲參考,進行Linux內存管理的研究:git
《奔跑吧 Linux內核》:以第2章爲藍本展開,這是目前能獲取的緊跟當前內核發展(Linux 4.0),而且講的比較全面的一本資料。github
《Understanding the Linux Virtual Memory Manager》:簡單說就是雖老但經典,基於(Linux 2.4/2.6)。做者是目前仍然活躍在Linux社區MM專家。算法
《wowotech Memory Management》:沒有其餘系列經典,也沒有條理系列的介紹MM,可是仍然值得按考。shell
《tolimit Linux內存源碼分析》:相對零散的介紹了內存相關分析文檔express
《Linux Kernel v4.0》:固然必不可少的,是源碼了。ubuntu
當逐漸深刻看到MMU相關代碼時,讀一下ARM架構關於MMU的規格書有助於理解。小程序
否則對於虛擬地址到物理地址的映射就會很虛無,這些資料包括《ARM Architecture Reference Manual ARMv7-A and ARMv7-R edition》的《Virtual Memory System Architecture》,以及相關MMU TRM。數據結構
整個內存管理從宏觀上能夠分爲三大部分:用戶空間、內核空間和相關硬件。
用戶空間主要是libc對相關係統調用進行封裝,對用戶程序提供API,經常使用的有malloc、mmap、munmap、remap、madvise、mempolicy等等。
相關硬件包括MMU/TLB、L1/L2 Cache以及DDR RAM,具體到ARM架構須要對照MMU/L2 Cache以及RAM規格書。
內核空間就複雜多了,首先介紹初始化及初始化後的佈局。
2.1 物理內存初始化從獲取內存大小、初始化頁表,再進行zone初始化,而後在zone中使用夥伴系統進行物理內存初始化;
2.2 頁表的映射過程講述了ARM32和ARM64兩種架構下的頁表映射,如何從虛擬地址由MMU轉化成物理頁面地址的;
2.3 內核內存的佈局圖在內存被初始化以後,內核的內存佈局基本上就肯定了,ARM32和ARM64下佈局有很大區別。在malloc一節brk中介紹了用戶空間的佈局。
2.1~2.3是內存的一個靜態狀態,在有了這些基礎以後,2.4~2.9按照從低層到上層的逐個介紹了。
2.4 分配物理頁面介紹了基於夥伴系統的頁分配和釋放;
2.5 slab分配器基於夥伴系統,slab分配更小內存塊;以及基於slab的kmalloc;
2.6 vmalloc和kmalloc區別在於v,即在VMALLOC區域分配;
2.7 VMA即Virtual Memory Area,是進程內存管理的核心;
2.8 malloc和2.9 mmap都基於VMA,malloc/free用於分配/釋放一塊內存;mmap/munmap用於匿名/文件映射到用戶空間。以及mmap(補充)。
因爲malloc/mmap分配內存並非當即分配,只是在用到的時候纔會觸發2.10 缺頁中斷處理。
在缺頁但頁不足的狀況下,就須要進行一些操做調整內存,這些操做的基礎是2.11 page引用計數,還有頁面的2.12 反向映射RMAP技術。
在內存不足狀況下觸發kswapd2.13 回收頁面,其中匿名頁面有着特殊的2.14 匿名頁面生命週期。
在kswapd回收依然沒法知足內存分配,就須要對內存進行2.16 內存規整,它依賴的技術是2.15 頁面遷移。
因爲內存中存在一些內容徹底同樣的頁面,使用2.17 KSM技術進行合併,同時利用COW技術,在須要時從新分配。
還介紹了2.18 Dirty COW內存漏洞,而後對內存管理數據結構和API進行了總結2.19 總結內存管理數據結構和API。
最後2.20 最新更新和展望對新技術進行了介紹。
除了以上技術,還有以下內存技術:
==============================================================================================================================
在對內存相關技術瞭解事後,就是如何運用的問題了?
一方面是對內存問題進行定位;另外一方面是對內存行爲施加影響,進行優化。
22 內存檢測技術對Linux內存常見問題及其定位方法和工具(slub_debug/kmemleak/kasan)進行了講解。
23 一個內存Oops解析以一個內存Oops爲例,介紹了內存相關異常分析。
內存sysfs節點和工具介紹了linux內存管理相關sysfs節點,以及工具;藉助這些能夠對內存進行優化。
擴展閱讀:
Linux內存管理框架圖
安裝QEMU以及相關編譯工具
sudo apt-get install qemu libncurses5-dev gcc-arm-linux-gnueabi build-essential
下載Busybox 1.24代碼:
git clone https://github.com/arnoldlu/busybox.git -b 1_24_stable
編譯Busybox:
export ARCH=arm
export CROSS_COMPILE=arm-linux-gnueabi- #make menuconfig #P684,進行配置 make -j4 install
配置initramfs:
sudo cp -r running_kernel_initramfs/* _install/ sudo chmod +x _install/etc/init.d/rcS cd _install mkdir mnt mkdir dev cd dev sudo mknod console c 5 1 sudo mknod null c 1 3
下載Linux Kernel 4.0代碼:
git clone https://github.com/arnoldlu/linux.git -b running_kernel_4.0
編譯Linux Kernel:
export ARCH=arm
export CROSS_COMPILE=arm-linux-gnueabi-
make vexpress_defconfig #P685進行配置 make bzImage -j4 ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- make dtbs
#Run Kernel+Busybox in QEMU
qemu-system-arm -M vexpress-a9 -smp 4 -m 1024M -kernel arch/arm/boot/zImage -append "rdinit=/linuxrc console=ttyAMA0 loglevel=8" -dtb arch/arm/boot/dts/vexpress-v2p-ca9.dtb -nographic
至此,已經有一個完整的環境,提供shell命令。