linux内核源码分析之内存概述
目录内存相关术语MMUslab虚拟内存空间内存申请内存释放内存检测工具内存相关术语主存:也称为物理内存,描述计算机的高速数据存储区域,通常是动态随机访问内存(DRAM)虚拟内存:抽象的主存概念常驻内存:当前处于主存中的内存匿名内存:无文件系统或者路径名的内存,它包括进程地址空间的工作数据,称作堆地址空间:内存上下文。段:标记为特殊用途的一块内存区域,例如用来存储可执行或者可写的页OOM:内存耗尽,
目录
内存相关术语
主存:也称为物理内存,描述计算机的高速数据存储区域,通常是动态随机访问内存(DRAM)
虚拟内存:抽象的主存概念
常驻内存:当前处于主存中的内存
匿名内存:无文件系统或者路径名的内存,它包括进程地址空间的工作数据,称作堆
地址空间:内存上下文。
段:标记为特殊用途的一块内存区域,例如用来存储可执行或者可写的页
OOM:内存耗尽,内核检测到可用内存低
页:操作系统和CPU使用的内存单位。4kB或者8kB
缺页:无效内存访问,使用按虚拟内存时,这是正常事件
换页:在主存与存储设备间交换页。
交换:页面转移到交换设备
CPU 缓存:
处理器通常在芯片中包含硬件缓存以提高内存访问性能,这些缓存可能包含如下级别
- L1:通常分为指令缓存和数据缓存
- L2:同时缓存指令和数据
- L3:更大一级的缓存
一级缓存通常按虚拟内存地址空间寻址,二级及以上按物理内存地址寻址,具体取决于处理器。
MMU
内存管理单元(MMU)负责虚拟到物理地址的转换。将虚拟内存地址映射到物理内存地址。内核为每个进程都维护了一张页表,记录虚拟地址与物理地址的映射关系。
按页做转换,而页内的偏移量则直接映射。
slab
Linux 使用伙伴分配器管理页,它以2的幂的方式向不同尺寸的内存分配器提供多个空闲链表。伙伴值找到相邻的空闲内存页以被同时分配。
伙伴空闲链表处于如下等级结构的低端,起始于每个内存节点pg_data_t
- 节点:内存库,支持NUMA
- 区域:特定用途的内存区域(直接内存访问(DMA)、普通、高位内存)
- 迁移类型:不可移动,可移动,可回收
- 尺寸:数量为2的幂次方的页面
在节点的空闲链表分配能提高内存的本地性和性能
虚拟内存空间
- 只读段:包括代码和常量等;
- 数据段:包括全局变量等;
- 堆:包括动态分配的内存;
- 文件映射段:包括动态库、共享内存等;
- 栈:包括局部变量和函数调用的上下文等,栈的大小一般是 8 MB
内存申请
brk() :小块内存,内存释放后并不会立刻归还系统,而被缓存起来,可以重复使用。
优点:可以减少缺页异常的发生,提高内存访问效率。不过,由于这些内存没有归还系统, 缺点:在内存工作繁忙时,频繁的内存分配和释放会造成内存碎片。
mmap() :大块内存,在文件映射段找一块空闲内存分配。
释放时直接归还系统,每次 mmap 都会发生缺页异常,使内核的管理负担增大。
用户态在申请分配后,只有在首次访问时才分配,也就是通过缺页异常进入内核中,再由内核来分配内存。
内存释放
1)free() 或 unmap()
2)系统中可用内存过低时,多种释放方法
- 回收:内存低于某个阈值(vm.min_free_kbytes)时,内核模块和内核分配器会立刻释放任何可以轻易释放的内存。大多数是从内核的slab分配器缓存释放内存,这些缓存包含slab大小的未使用内存块以供重用。回收将这些内存交给系统进行分配。Linux内核模块可以调用register_shrinker()以注册特定的函数回收自己的内存。
- 交换:页面换出守护进程(kswapd)执行的换页,找出最近不使用的页并加入到空闲链表中,其中包括应用空间内存。
- OOM:内存耗尽终结者搜索并杀死可牺牲的进程以释放内存,采用select_band_process()搜索而后用oom_kill_process()杀死进程。系统dbg信息有Out of memory。
换页时,换页倾向 0~100范围的参数(默认60).较高的值更倾向于用换页释放内存,而较低的值更倾向于回收缓存。这就通过保留热文件系统缓存的同时,换出冷应用程序的内存页面来提高系统吞吐量。
内存检测工具
页扫描:寻址连续的页扫描(超过10秒),它是内存压力的预兆;
换页:换页是系统内存低的进一步征兆。vmstat 检查si 和 so列;
vmstat:每秒运行vmstat检查free列可用内存;
oom:日志信息/var/log/messages查看;
top/prostat:查看哪些进程和用户是物理内存和虚拟内存的最大使用者;
dtrace/perf/stap:内存分配的栈跟踪,确认内存使用的原因。
参考:
《深入理解linux内核》
《Linux内核深度解析》
更多推荐
所有评论(0)