- 论坛徽章:
- 0
|
前段时间发现服务器会出现短暂访问异常缓慢的情况,top发现是kswapd 100%引起的。服务器上面跑的memcached、mongodb,这些都是内存大户。借着这个机会,正好分析了swap以及内存管理相关的原理,跟大家交流一下心得。
1.linux内存管理涉及的概念有:page、zone、node、页目录、页表。
分页单元把所有的RAM分成固定长度的页框,每个页框包含一个页。
页目录项和页表都具有present字段,表明page是否在主存中,如果present标志被清0,那么分页单元就把该线性地址存放cr2中,产生缺页异常。
页框的状态信息保存在page页描述符中,所有的页描述符存放在mem_map数组中。page的_count是页引用计数器,_flags字段描述页框状态PG_xxxx。
NUMA中,根据内存单元的访问时间划分为node,在一个单独的节点,任意给定CPU访问页面所需的时间都是相同。用pg_data_t来描述。
每个节点的物理内存又可分为几个管理区zone。zone分为ZONE_DMA,ZONE_NORMAL,ZONE_HIGHMEM,
管理区描述符里面,比较重要的字段有free_pages pages_min pages_low pages_high free_area
2.管理区zone
pages_min 管理区中保留页的数目
pages_low 回收页框使用的下界、同时也被管理区分配器作为阈值使用
pages_high 回收页框使用的上界、同时也被管理区分配器作为阈值使用
3.管理区分配器
管理区分配器接受动态内存分配与释放的请求,在请求分配的情况下,搜索一个能满足请求的一组连续页框内存的管理区,在每个管理区内,页框由buddy system来处理。
请求页框:
alloc_pages --> alloc_page --> __get_free_pages --> __get_free_page
释放页框:
free_pages free_page
__rmqueue() 函数用来在管理区找到一个空闲块
__free_pages_bulk()函数按照buddy system的策略释放页框
__alloc_pages()函数,会对内存管理区扫描,配合z->pages_min 、z->pages_low、z->pages_high标志,如果没有剩下多少空闲内存,会唤醒kswapd内核线程来异步地开始回收页框。
4.获得动态内存方式:
__get_free_pages或alloc_pages 从页框分配器中获取页框;
kmem_cache_alloc 或kmalloc 使用slab分配器为专用或通用对象分配块;
vmalloc 获得一块非连续的内存区。 |
|