啃了一下的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
Mem: 100 60 40 0 10 10
-/+ 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的角度。