谈到内存管理,要理解以下基本概念:
实际上,用户程序一般只面对虚拟内存,知道执行的时候才通过MMU根据内核中的页表将page和page frame进行对应。
首先,所有操作系统都是基于虚拟地址来进行内存管理,虚拟地址的空间就是cpu寻址空间来限定。例如32bit的cpu,寻址空间就是232Gb。不管机器上安装了多少实际的内存条,所有在上面运行的程序(包括内核)都认为自己有4Gb的内存可以使用。
内存布局就是如何安排这4Gb的内存。
内核空间、用户空间(堆、栈、代码域、静态数据域和mmap区)
内核空间和用户空间都需要对虚拟内存的分配进行管理,内核通过(kmalloc(小内存,但是物理和虚拟地址都连续)和vmalloc(大内存,但是不保证连续))来使用内存,管理采用slab分配器和buddy机制。为什么需要管理机制,因为,无论虚拟内存还是物理内存,其最小分配单位是页(每页4k)。
用户空间通过(malloc(brk(堆上分配,小于128k),mmap(映射区分配,大于128k))),管理采用ptmalloc,tcmalloc,jemalloc来进行。
用户空间有一些自己写的cache(情况简单时)和专用内存池(情况复杂时),这种机制通常基于通用内存管理malloc来运行,策略经常是:
1.当频繁(malloc/free)发生时,就可以采用长期占用(启动时申请后,一直不释放)一块大的内存作为cache使用的策略。减少大内存的申请操作(大内存都是在映射区进行,每次malloc/free会产生真正申请和释放内存(虚拟内存和物理内存),需要修改进程的页表,会产生mmap系统调用和缺页中断,这个太糟糕了)
2.专用内存池:基于连接的内存管理,就是类似于nginx这种服务器,基于connection的策略是:一次连接会有各种各样变长的字符串和小内存,连接建立时,create memory pool,创建专用的内存池进行(内存管理),连接进行时采用memory pool来对连接所需的数据结构进行管理,然后一次性释放(连接关闭时,delete memory pool)。
阅读(1333) | 评论(0) | 转发(0) |