接下来一段时间打算整理一下Linux内存管理的内容,一是为了梳理、巩固之前的所学,二是为了从全局、从更高层次上来窥探Linux内存管理的精髓。
    本文以x86的NUMA模型进行描述,所涉及的内容均基于内核版本Linux-v3.2.40。

先上个图,看一下Linux中内存的布局情况,然后对几个术语进行说明:

在NUMA模型中,每个CPU都有自己的本地内存节点(memory node),而且还可以通过QPI总线访问其他CPU下挂的内存节点,只是访问本地内存要比访问其他CPU下的内存的速度高许多,一般经过一次QPI要增加30%的访问时延。
    Linux中对所有的内存进行统一管理,但由于关联不同的CPU导致访问速度不同,因此又将内存划分为节点(node);在节点内部,又进一步细分为内存域(zone)。

1. 内存节点(node)
    由挂在同一个CPU下的一片连续的物理内存组成,在内核中使用pg_data_t进行抽象。

typedef struct pglist_data {struct zone node_zones[MAX_NR_ZONES]; /* 该node包含的zone */struct zonelist node_zonelists[MAX_ZONELISTS];int nr_zones; /* 该node中zone的个数 */
#if 1 //#ifdef CONFIG_FLAT_NODE_MEM_MAP    /* means !SPARSEMEM */struct page *node_mem_map; /* struct page 指针数组,管理该node下的所有物理page */unsigned long node_start_pfn; /* 该node的开始页帧号 */unsigned long node_present_pages; /* 该node中物理page的个数 total number of physical pages *//* 该node空间以页帧为单位计算的个数,可能大于物理page的个数,因为可能存在空洞 */unsigned long node_spanned_pages; /* total size of physical pagerange, including holes */int node_id; /* 该node的id */wait_queue_head_t kswapd_wait;/* 指向负责回收该node中内存的swap内核线程kswapd,一个node对应一个kswapd */struct task_struct *kswapd;    /* Protected by lock_memory_hotplug() */} pg_data_t;

pg_data_t中描述了node的所有基本元素:
    1)  node_zones : 该node包含的内存域zone
    2)  node_zonelists :该node的备选节点及内存域列表,后面会详细说明。
    3)  node_mem_map :linux为每个物理页分配了一个struct page的管理结构体,并形成了一个结构体数组,node_mem_map即为数组的指针;pfn_to_page和page_to_pfn都借助该数组实现。
    4)  node_start_pfn :该node中内存的起始页帧号
    5)  node_present_pages :该node中所有的物理page页数
    6)  node_spanned_pages :该node地址范围内的所有page页数,包括空洞;目前还不清楚什么情况导致与 node_present_pages不同。
    7) kswapd:负责回收该node内存的内核线程,每个node对应一个内核线程kswapd。

1.2 全局node数组
    在NUMA模型中,必定存在多个node节点, 因此为了快速访问各个节点的内容,内核维护了一个全局的pg_data_t的指针数组 node_data[] ,只要根据node id即可快速找到对应的pg_data_t。

2. 内存域(zone)
    由于一些特殊的应用场景,导致只能分配特定地址范围内的内存(比如老式的ISA设备DMA时只能使用前16M内存;比如kmalloc只能分配低端内存,而不能分配高端内存),因此在node中又将内存细分为zone。

2.1 zone的类型
    1)  ZONE_DMA :定义适合DMA的内存域,该区域的长度依赖于处理器类型。比如ARM所有地址都可以进行DMA,所以该值可以很大,或者干脆不定义DMA类型的内存域。而在IA-32的处理器上,一般定义为16M。
   2)  ZONE_DMA32 :只在64位系统上有效,为一些32位外设DMA时分配内存。如果物理内存大于4G,该值为4G,否则与实际的物理内存大小相同。
   3)  ZONE_NORMAL :定义可直接映射到内核空间的普通内存域。在64位系统上,如果物理内存小于4G,该内存域为空。而在32位系统上,该值最大为896M。
   4)  ZONE_HIGHMEM :只在32位系统上有效,标记超过896M范围的内存。在64位系统上,由于地址空间巨大,超过4G的内存都分布在ZONE_NORMA内存域。    
   5)  ZONE_MOVABLE :伪内存域,为了实现减小内存碎片的机制。

2.2 数据结构

struct zone {/* zone watermarks, access with *_wmark_pages(zone) macros */unsigned long watermark[NR_WMARK]; /* 内存回收的水线 *//** We don't know if the memory that we're going to allocate will be freeable* or/and it will be released eventually, so to avoid totally wasting several* GB of ram we must reserve some of the lower zone memory (otherwise we risk* to run OOM on the lower zones despite there's tons of freeable ram* on the higher zones). This array is recalculated at runtime if the* sysctl_lowmem_reserve_ratio sysctl changes.*//* 为各个内存域指定的保留内存,用于分配不能失败的关键性内存分配 */unsigned long        lowmem_reserve[MAX_NR_ZONES];#ifdef CONFIG_NUMAint node; /* 该zone所属的node的node id *//** zone reclaim becomes active if more unmapped pages exist.*//* 对应的page个数大于这两个值时,开始进行回收 */unsigned long        min_unmapped_pages;unsigned long        min_slab_pages;
#endif/* 为什么是per-cpu? * 因为每个cpu都可从当前zone中分配内存,而pageset本身实现的一个功能就是批量申请和释放* 修改为per-cpu可减小多个cpu在申请内存时的所竞争*/struct per_cpu_pageset __percpu *pageset;/** free areas of different sizes*/spinlock_t        lock;struct free_area    free_area[MAX_ORDER]; /* 空闲内存链表,按幂次分组,用于实现伙伴系统 *//* Fields commonly accessed by the page reclaim scanner */spinlock_t        lru_lock;    struct zone_lru lru[NR_LRU_LISTS]; /* 用于链接各种类型的page */ struct zone_reclaim_stat reclaim_stat;unsigned long        pages_scanned;     /* 上一次回收扫描过的page数 since last reclaim */unsigned long        flags;         /* zone flags, see below *//* Zone statistics */atomic_long_t        vm_stat[NR_VM_ZONE_STAT_ITEMS]; /* 内存状态统计 *//** The target ratio of ACTIVE_ANON to INACTIVE_ANON pages on* this zone's LRU. Maintained by the pageout code.*/unsigned int inactive_ratio;/** Discontig memory support fields.*/struct pglist_data    *zone_pgdat;/* zone_start_pfn == zone_start_paddr >> PAGE_SHIFT */unsigned long        zone_start_pfn; /* 该zone的起始页帧号 *//** zone_start_pfn, spanned_pages and present_pages are all* protected by span_seqlock. It is a seqlock because it has* to be read outside of zone->lock, and it is done in the main* allocator path. But, it is written quite infrequently.** The lock is declared along with zone->lock because it is* frequently read in proximity to zone->lock. It's good to* give them a chance of being in the same cacheline.*/unsigned long        spanned_pages;    /* total size, including holes */unsigned long        present_pages;    /* amount of memory (excluding holes) */
} ____cacheline_internodealigned_in_smp;

zone的数据结构比较庞大,这里只对几个关键字段进行说明:
    1)  wartermark :定义内存回收的水线,有三种水线:WMARK_HIGH、WMARK_LOW、WMARK_MIN。内核线程kswapd检测到不同的水线值会进行不同的处理,当空闲page数大于high时,内存域状态理想,不需要进行内存回收;当空闲page数低于low时,开始进行内存回收,将page换出到硬盘;当空闲page数低于min时,表示内存回收的压力很重,因为内存域中的可用page数已经很少了,必须加快进行内存回收。
    2)  pageset :per-cpu变量,用于实现每cpu内存的批量申请和释放,减小申请内存时的锁竞争,加快分配内存的速度。
    3)  free_area :空闲内存链表,按order进行分组,构建伙伴系统模型。同时,如上图所示,为了减少内存碎片,每种order下又根据迁移类型进行了分类,该部分内容后续会进行进一步的解释。free_area数组是停用bootmem分配器、释放bootmem内存时建立起来的。
    4)  vmstat :用于维护zone中的大量统计信息,在同步和内存回收时非常有用。

2.3 内存“价值”层次结构
    内核为内存域定义了一个“价值”的层次结构,按分配的“廉价度”依次为: ZONE_HIGHMEM >  ZONE_NORMAL >  ZONE_DMA。
    高端内存域是最廉价的,因为内核没有任何部分依赖于从该zone中分配内存, 如果高端内存用尽,对内核没有任何副作用,这也是优先分配高端内存的原因。
    普通内存域有所不同,因为所有的内核数据都保存在该区域,如果用尽内核将面临紧急情况,甚至崩溃。
    DMA内存域是最昂贵的,因为它不但数量少很容易被用尽,而且被用于与外设进行DMA交互,一旦用尽则失去了与外设交互的能力。
    因此内核在进行内存分配时,优先从高端内存进行分配,其次是普通内存,最后才是DMA内存。

3. 备选节点及其内存域列表(node_zonelists)
    从前面的分析可以知道,zone是进行内存分配的基本容器,如果从某个zone申请内存失败后怎么办呢?这就是node_zonelists将要发挥的作用。
    node_zonelists定义了一个zone搜索列表(每一项代表一个zone),当从某个node的某个zone申请内存失败后,会搜索该列表,查找一个合适的zone继续分配内存。
    该列表有两种排列形式,下面以例子进行说明:
    假设某NUMA系统有4个内存节点,分别标记为A、B、C、D,每个内存节点有3个内存域, ZONE_DMA、 ZONE_NORMAL、 ZONE_HIGHMEM,分别标记为0、1、2。其模型如下:

 1) 按node进行排序:优先选择距离较近的node,再选择比较廉价的zone
    node_zonelists列表如下:

或者

可能存在两种列表是因为A到B和A到D的距离是一样的。
    2) 按zone进行排序:优先选择比较廉价的zone,再选择距离较近的node
    node_zonelists列表如下:

或者

可能存在两种列表是因为A到B和A到D的距离是一样的。

还有一个关键的数据结构struct page由于太复杂也太重要,后面单独进行介绍。

node zone相关推荐

  1. Linux内核:内存从BIOS->e820->memblock->node/zone基本流程

    1. 从 BIOS 到 E820(见 e820.txt 文档)```e820__memory_setup_default BIOS ------------------------------> ...

  2. Linux内存管理:内存描述之内存区域zone

    目录 1 前景回顾 1.1 UMA和NUMA两种模型 1.2 (N)UMA模型中linux内存的机构 1.3 Linux如何描述物理内存 1.4 用pd_data_t描述内存节点node 1.5 今日 ...

  3. 深入理解Linux内核---内存管理zone

    转载:https://blog.csdn.net/gatieme/article/details/52384529 https://blog.csdn.net/gatieme/article/deta ...

  4. 从零开始入门 K8s | 调度器的调度流程和算法介绍

    作者 | 汪萌海(木苏)  阿里巴巴技术专家 关注"阿里巴巴云原生"公众号,回复关键词**"入门"**,即可下载从零入门 K8s 系列文章 PPT. 导读:Ku ...

  5. 云原生生态周报 Vol. 16 | CNCF 归档 rkt,容器运行时“上古”之战老兵凋零

    作者列表:木苏,临石,得为,等等 业界要闻 安全漏洞 CVE-2019-9512 CVE-2019-9514 http2 的 DOS 漏洞,一旦攻击成功会耗尽服务器的 cpu/mem,从而导致服务不可 ...

  6. elasticsearch文档-modules

    2019独角兽企业重金招聘Python工程师标准>>> modules 模块 cluster 原文 基本概念 cluster: 集群,一个集群通常由很多节点(node)组成  nod ...

  7. Liunx 系统调优

    Sysctl命令用来配置与显示在/proc/sys目录中的内核参数.如果想使参数长期保存,可以通过编辑/etc/sysctl.conf文件来实现. 命令格式: sysctl [-n] [-e] -w ...

  8. linux内核那些事之struct page

    struct page page(页)是linux内核管理物理内存的最小单位,内核将整个物理内存按照页对齐方式划分成千上万个页进行管理,内核为了管理这些页将每个页抽象成struct page结构管理每 ...

  9. linux内核那些事之物理内存模型之SPARSE(3)

    在内核FLAT和DISCONTIGMEM管理模型中,其实一直都存在两个问题 管理物理内存的数据结构本身占用内存较多,不使用于较大内存情况 无法解决空洞问题,不管是FLAT还是SPARCE模型都无法解决 ...

最新文章

  1. 拼多多就知乎不当评论致歉!相关部门已展开调查
  2. 翻译:MariaDB RENAME TABLE语句
  3. 一次授权测试引起的全域名沦陷
  4. 02_Nginx基本配置与参数说明 + 辅助命令
  5. ACOUG China Tour 2019上海站,等你来约!
  6. 这家中国企业和星巴克对着干 年亏16亿却成为全球最快上市公司
  7. 使用Aop管理所有Valid结构bindingResult
  8. 也许现在的前端,应该了解更多的算法
  9. quartus仿真28:JK触发器实现的脉冲分配器(分析)
  10. 简单的扫雷游戏代码(c++)
  11. 如何使用linux command line 利用Entrez Direct下载NCBI数据
  12. 吉林公主岭玉米丰收将成定局
  13. 三星980处理器和骁龙855_手机处理器最新排名:麒麟980因一缺陷,不敌高通骁龙855...
  14. 6个不为人知的高质量APP推荐:知乎3万人点赞,2万人收藏!
  15. 聊聊写代码的20个反面教材
  16. 怎么查百度竞价外地排名情况
  17. MTK-手机锁等相关密码配置
  18. AutoJS4.1.0实战教程 ---火火视频极速版
  19. 你想三年后过上什么样的生活?
  20. 走进Linux 操作系统(ZT)

热门文章

  1. 解决在VMware上安装windows10全屏有黑边的问题
  2. raid卡组不同raid_游戏王决斗链接 戈德温地缚神Raid战活动指北抛砖(Duel Links)...
  3. 互联网行业领域细分 | 你可以准确的说出你混哪个圈的吗?
  4. 初中计算机课标考试,初中信息技术课程标准试题(含答案)
  5. 2022建筑施工企业数字化转型前景和趋势
  6. 《设计模式》适配器模式
  7. 二进制,十进制,十六进制互相转化
  8. Git仓库、Jenkins搭建、应用Jenkins、管理应用服务器
  9. 如何正确使用防关联浏览器
  10. 算法题解(剑指Offer篇)