啃了一下的Linux的內存管理部分,大概框框理解了一下,下面自己總結下備忘。
1. 內存管理涉及的概念很多,包括地址映射、虛擬地址空間等等。
2. 內存管理主要分爲內核的內存管理以及進程(用戶空間)的內存管理,內核一般使用1G,進程使用3G。
3. 進程的內存管理:(小內存brk實現,大內存mmap實現)
1)進程所使用的內存是虛擬地址,並不是直接的物理內存,中間需要一定的機制進行映射,這裏不討論映射機制,瞭解即可。
2)每個進程需要用到內存的主要有text、data、bss、heap、stack,就是一些程序、變量等,主要分兩類,靜態分配的關於變量等,動態分配的使用heap的,這裏主要學習動態分配的heap(堆)。(靜態分配會自動釋放,動態分配要手工free釋放)
3)進程如何動態分配內存:使用malloc()函數,就可以取得內存。
4)虛擬地址與物理地址:進程通過malloc()獲得的只是虛擬地址空間,並未實際佔用物理內存,直到真正使用的時候才進行地址映射,取得物理內存的空間。
5)malloc細節:glibc的函數maloc通過系統調用brk()或mmap()來分配內存。
小塊內存(<=128kbytes),使用brk()
大塊內存(>128kbytes),使用mmap()
6)brk():是堆機制,內存分配一直往上堆,儘量先從現有的堆中分配,沒有的話,通過brk()增大堆。這裏涉及如何分配的各種算法,這裏不討論。
7)mmap():大塊內存的時候申請。
8)重點_brk()的free:如果是通過brk()申請的空間,使用free()釋放後,並不會馬上釋放給系統,而是釋放給glibc管理器統一分配協調。glibc是通過查看堆頂的連續空間是否有大於一定的值,如果有的話,才進行釋放,否則不釋放。
例子:如果進程申請了10塊堆的空間,其中9塊已經釋放了,有1塊在離堆頂最近的地方但是沒有釋放,那麼這十塊就都沒有辦法釋放。
9)mmap()的free:mmap會直接free掉,不會出現brk()的問題。
4. 內核的內存管理:通過slab機制,主要解決小內存的問題。
1)內核的內存主要有對象和控制結構使用。
2)slab爲內核中常用的對象建立專門的對象池,比如task結構的池。
3)維護通用的對象池,比如32字節大小的對象池
4)控制結構有兩種方式,如果控制結構較大,使用專門的頁面,如果較小,使用對象池。
5. 內存管理的緩存:內存中會有一部內存被暫時保存,以便下次調用的時候不需要重新分配和初始化,主要有cache和buffer兩種類型。只有等到系統內存不夠的時候,
可以用cache和buffer中的內存,所以可以這裏理解cache和buffer:是已經分配但是當前不可用的內存,當系統內存不足的時候可以用。
6. free命令:
total used free shared buffers cached
-/+ buffers/cache: 40 60
Swap: 10 10 10
簡單解釋下:buffers和cached就是已經分配,但是還未用的。
Mem:這一行的used就是包括buffer/cache的,free就是當前目前馬上可用的。
第3行:used是不包括buffer/cache的,就是實際使用的,free是包括buffer和cache的。
總結下:其實就是從2個角度看系統內存的狀態,一個是從不算上buffer和cache的角度,一個是算上cache/buffer的角度。