2023-06-11  阅读(4)
原文作者:奇小葩 原文地址:https://blog.csdn.net/u012489236/category_9614673.html

上一章我们梳理了Node, Zone, Page Frame的整个流程,本章就来整理其关系和数据结构之间的关系。

1. 基本概念

NUMA(Non-Uniform Memory Access,非统一内存访问)和UMA(Uniform Memory Access,统一内存访问):

  • NUMA是从处理器对内存访问速度不同的结构
  • UMA是处理器与所有内存的访问速度相同的结构

结点Node:

  • 从1个CPU访问速度相同的内存集合
  • 每个CPU对应一个本地物理内存
  • 在内核中用pg_data_t类型,表示节点的结构体成为节点描述符

ZONE:

  • 节点中具有相同属性的区域
  • 内核使用struct zone结构体管理

页帧Page:

  • ZONE中管理物理内存的最小单位称为页帧
  • 页帧在Linux中由page结构体管理,通过mem_map全局数据访问

Linux采用Node、Zone和页三级结构来描述物理内存的,如图所示

202306111240324911.png

2. 结点

Linux采用一个struct pg_data_t结构体来描述系统的内存,每一个Node都对应一个struct pglist_data,系统中每个节点都挂接在一个pgdat_list列表中,对于NUMA系统中一个,使用的全局变量struct pglist_data __refdata contig_page_data

下面就对结构体提的主要域进行说明

结构体成员变量 说明
node_zones 该结点的zone类型,一般包括ZONE_HIGHMEM、ZONE_NORMAL和ZONE_DMA三类,包含了节点中各个内存域的数据结构
node_zonelists 指定了备用节点及其内存域列表,以便在当前结点没有可用空间时,在备用结点分配内存
nr_zones 该结点的zone个数,可以从1到3,但并不是所有的结点都需要有3个zone
node_mem_map 它是structpage数组的第一页,该数组表示结点中的每个物理页框。根据该结点在系统中的顺序,它可在全局mem_map数组中的某个位置
node_start_pfn 当前NUMA节点第一页帧逻辑编号。在UMA总是0.
node_present_pages 总共可用的页面数
node_spanned_pages 总共的页面数,包括有空洞的区域
kswapd 页面回收进程

3. ZONE

每个结点的内存被分为多个块,称为zones,它表示内存中一段区域。一个zone用struct_zone_t结构描述,zone的类型主要有ZONE_DMA、ZONE_NORMAL和ZONE_HIGHMEM。ZONE_DMA位于低端的内存空间,用于某些旧的ISA设备,ISA总线的直接内存存储DMA,只能对RAM的前16MB进行寻址。ZONE_NORMAL的内存直接映射到Linux内核线性地址空间的高端部分,许多内核操作只能在ZONE_NORMAL中进行。因此对于内核来说, 不同范围的物理内存采用不同的管理方式和映射方式,Linux使用enum zone_type来标记内核所支持的所有内存区域

    enum zone_type
    {
    #ifdef CONFIG_ZONE_DMA
        ZONE_DMA,
    #endif
    #ifdef CONFIG_ZONE_DMA32
        ZONE_DMA32,
    #endif
        ZONE_NORMAL,
    #ifdef CONFIG_HIGHMEM
        ZONE_HIGHMEM,
    #endif
        ZONE_MOVABLE,
    #ifdef CONFIG_ZONE_DEVICE
        ZONE_DEVICE,
    #endif
        __MAX_NR_ZONES
    }

其定义如下表所示

管理内存域 描述
ZONE_DMA 标记了适合DMA的内存域.该区域的 长度依赖于处理器类型 .这是由于古老的ISA设备强加的边界.但是为了兼容性,现代的计算机也可能受此影响
ZONE_DMA32 标记了 使用32位地址字可寻址,适合DMA的内存域 ,在 32位系统中,本区域是空的 ,即长度为0MB,在Alpha和AMD64系统上,该内存的长度可能是从0到4GB
ZONE_NORMAL 标记了可 直接映射到内存段的普通内存域 .这是在 所有体系结构上保证会存在的唯一内存区域 
ZONE_HIGHMEM 标记了 超出内核虚拟地址空间 的 物理内存段 ,因此这段地址 不能被内核直接映射 
ZONE_MOVABLE 内核定义了一个伪内存域ZONE_MOVABLE,在 防止物理内存碎片的机制memorymigration中需要使用 该内存域.供防止 物理内存碎片的极致使用 
ZONE_DEVIC 为支持 热插拔设备 而分配的NonVolatileMemory非易失性内存

Zone是用struct zone_t描述的,它跟踪页框使用、空闲区域和锁等信息,结构体中主要域说明如下

结构体成员变量 说明
watermark 水位值,WMARK_MIN/WMARK_LOV/WMARK_HIGH,页面分配器和kswapd页面回收中会用到
lowmem_reserve zone中预留的内存,用于一些无论如何都不能失败的关键性内存分配
zone_pgdat 执行所属的pglist_data
pageset Per-CPU上的页面,减少自旋锁的争用
zone_start_pfn ZONE的起始内存页面帧号
managed_pages 被BuddySystem管理的页面数量
spanned_pages ZONE中总共的页面数,包含空洞的区域
present_pages ONE里实际管理的页面数量
structfree_areafree_area[MAX_ORDER]; 管理空闲页面的列表

当系统中可用的内存比较少时,kswapd将被唤醒,并进行页交换。如果需要内存的压力非常大,进程将同步释放内存。每个zone有三个阙值,成为pages_low/pages_min/pages_high,用于跟踪该zone的内存压力。

  • pages_min的页框数是由内存初始化free_area_init_core函数,根据zone内页框的比例计算,最小为20页,最大一般为255页
  • 当到达pages_min时,说明页面数非常紧张,分配页面的动作和kswapd线程同步运行
  • 当空闲也的数目达到pages_low时,说明页面刚开始紧张,则kswapd线程将被唤醒,并开始释放回收页面
  • 当达到pages_high时,说明内存页面数很充足,不需要回收,kswapd线程将重新休眠,通常这个数值是page_min的3倍

4. page

每个物理页框都需要一个对应的page结构来进行管理,记录分配状态,分配和回收,互斥以及同步存在。 因为内核会为每一个物理页帧创建一个struct page的结构体,因此要保证page结构体足够的小,否则仅struct page就要占用大量的内存。出于节省内存的考虑,struct page中使用了大量的联合体union。

5. 总结

本章梳理了Node, Zone, Page Frame各个数据结构的成员变量和关系,对于Linux中管理内存的各个结构体之间的关系图如下图所示

202306111240335032.png


Java 面试宝典是大明哥全力打造的 Java 精品面试题,它是一份靠谱、强大、详细、经典的 Java 后端面试宝典。它不仅仅只是一道道面试题,而是一套完整的 Java 知识体系,一套你 Java 知识点的扫盲贴。

它的内容包括:

  • 大厂真题:Java 面试宝典里面的题目都是最近几年的高频的大厂面试真题。
  • 原创内容:Java 面试宝典内容全部都是大明哥原创,内容全面且通俗易懂,回答部分可以直接作为面试回答内容。
  • 持续更新:一次购买,永久有效。大明哥会持续更新 3+ 年,累计更新 1000+,宝典会不断迭代更新,保证最新、最全面。
  • 覆盖全面:本宝典累计更新 1000+,从 Java 入门到 Java 架构的高频面试题,实现 360° 全覆盖。
  • 不止面试:内容包含面试题解析、内容详解、知识扩展,它不仅仅只是一份面试题,更是一套完整的 Java 知识体系。
  • 宝典详情:https://www.yuque.com/chenssy/sike-java/xvlo920axlp7sf4k
  • 宝典总览:https://www.yuque.com/chenssy/sike-java/yogsehzntzgp4ly1
  • 宝典进展:https://www.yuque.com/chenssy/sike-java/en9ned7loo47z5aw

目前 Java 面试宝典累计更新 400+ 道,总字数 42w+。大明哥还在持续更新中,下图是大明哥在 2024-12 月份的更新情况:

想了解详情的小伙伴,扫描下面二维码加大明哥微信【daming091】咨询

同时,大明哥也整理一套目前市面最常见的热点面试题。微信搜[大明哥聊 Java]或扫描下方二维码关注大明哥的原创公众号[大明哥聊 Java] ,回复【面试题】 即可免费领取。

阅读全文