当前位置: 首页 > article >正文

Linux内核物理内存组织结构

一、系统调用sys_mmap

        系统调用mmap用来创建内存映射,把创建内存映射主要的工作委托给do_mmap函数,内核源码文件处理:mm/mmap.c

 二、系统调用sys_munmap

1、vma = find_vma (mm, start); // 根据起始地址找到要删除的第一个虚拟内存区域 vma
2、如果只删除虚拟内存区域 vam 的部分,那么分裂虚拟内存区域 vma
3、根据结束地址找到要删除的最后一个虚拟内存区域 vma
4、如果只删除虚拟内存区域 last 的一部分,那么分裂虚拟内存区域 vma
5、针对所有删除目标,若虚拟内存区域被锁定在内存中(不允许换出到交换区),调用函数解除锁定。
6、调用函数,将所有删除目标从进程虚拟内存区域链表和树中删除,单独组成临时链表。
7、调用函数,针对所有删除目标,在进程页表中删除映射,且从处理器页表缓存中删除映射。
8、调用函数执行处理器架构特定处

三、物理内存组织结构

1.体系结构

目前多处理器系统有两种体系结构:
        1)非一致内存访问(Non-Unit Memory Access,NUMA):指内存被划分成多个内存节点的多处理器系统,访问一个内存节点花费的时间取决于处理器和内存节点的距离。
        2)对称多处理器(Symmetric Multi-Processor,SMP):即一致内存访问(Uniform Memory Access,UMA),所有处理器访问内存花费的时间相同。

示例图如下:

2.内存模型

         内存模型是从处理器角度看到的物理内存分布,内核管理不同内存模型的方式存在差异。内存管理子系统支持 3 种内存模型:
        1)平坦内存(Flat Memory)
        2)不连续内存(Discontiguous Memory)
        3)稀疏内存(Space Memory)

平坦内存(Flat Memory)

  • 结构特点:将系统的物理内存视为一个连续的整体,所有内存地址线性排列,不存在内存分段或区间划分。虚拟地址空间和物理地址空间映射直接,就像一条连续的、没有断点的道路 。
  • 管理方式:简单直接,通常使用一个数组(如 struct page mem_map 数组 )来管理所有内存页,通过简单的地址偏移就能找到对应的物理内存页。
  • 优势
    • 简单高效:内存管理实现不复杂,地址转换简单,系统可直接访问内存,减少地址转换开销 。
    • 易于实现:适用于内存较小、硬件资源有限的架构,在早期计算机系统或一些小型嵌入式系统中应用较多。
  • 劣势:如果物理地址空间存在空洞(如某些地址范围不能被使用),会造成内存浪费,因为要为所有地址创建对应的管理结构 。
  • 举例:早期个人计算机内存容量较小且硬件相对简单,内存模型近似平坦内存模型,操作系统可简单地将内存按顺序划分和管理 ;一些简单的嵌入式设备,如简单的单片机系统,也常采用这种内存模型,因为其内存需求单一、硬件资源有限 。

不连续内存模型(Non-contiguous Memory Model)

        不连续内存模型是一种内存管理方式,内存分配的各个区域不要求在物理内存中连续,进程虚拟内存空间可映射到物理内存中分散、不连续的任意位置。
特点

 
  1. 物理内存不连续:内存无需物理连续,操作系统可将进程虚拟内存映射到物理内存的多个不连续区域。
  2. 内存管理灵活:支持更灵活的内存分配,高效使用内存,减少碎片。
  3. 页面管理:常见实现为分页内存管理,虚拟地址空间和物理内存划分为页面与页框,虚拟页通过页表映射到任意物理页。
    例子
 
  • 分页(Paging):内存划分为固定大小页面(如 4KB),虚拟地址与物理地址通过页表映射,虚拟页可映射到任意物理页,虚拟内存与物理内存不连续。

稀疏内存模型(Sparse Memory Model)

        稀疏内存模型指虚拟内存中部分区域不映射物理内存,甚至完全为空,虚拟内存空间非每块都对应物理地址,呈 “稀疏” 状态。
特点

 
  1. 内存区域稀疏:虚拟内存部分区域无实际物理内存映射,部分虚拟地址不对应物理地址。
  2. 懒加载:操作系统按需分配物理内存,如进程访问无对应物理内存的虚拟地址时,触发缺页异常后再分配内存。
  3. 高效内存使用:允许区域不映射物理内存,在大内存系统中减少不必要分配,提升内存使用效率。
    例子
 
  • 稀疏虚拟内存:操作系统不为大虚拟地址空间(如 64 位系统)全部分配物理内存,Linux 中mmapmprotect系统调用可创建无实际物理内存映射的稀疏区域。

3.三级结构

        内存管理子系统使用节点(node)、区域(zone)、页(page)三级结构描述物理内存。
a、内存节点 —— 分为两种情况:
(1)NUMA 体系的内存节点,根据处理器和内存的距离划分;
(2)在具有不连续内存的 NUMA 系统中,表示比区域级别更高的内存区域,根据物理地址是否连续划分,每块物理地址连续的内存是一个内存节点。

1.内存节点使用pglist_data结构体描述物理内存布局:(该结构体对应上图中的node)

         node_mem_map 此成员指向页描述符数组,每个物理页对应一个页描述符。
        Node 是内存管理最顶层的结构,在 NUMA 架构下,CPU 平均划分为多个 Node,每个 Node 有自己的内存控制器及内存插槽。CPU 访问自己 Node 上内存速度快,而访问其他 CPU 所关联 Node 的内存速度慢。UMA 被当做只一个 Node 的 NUMA 系统。

2.内存区域(zone)

结构体关系总结:

  • pglist_data 是管理一个 NUMA 节点的结构体,包含该节点所有的 zone
  • zone 代表内存的一个区域,管理着这个区域的页面和空闲页面的链表。
  • zonelist 是一个 zone 的列表,表示多个内存区域的优先级顺序。
  • zoneref 是对某个 zone 的引用,通常在内存分配上下文中使用。
pglist_data(对应内存节点 node)  |  |——> zone(多个 zone 组成内存节点的内存区域,如 ZONE_DMA、ZONE_NORMAL 等)  |       |  |       |——> page(每个物理页面由 struct page 描述符管理)  |  |——> zonelist(独立于 zone 的数据结构,是多个 zone 组成的链表,定义内存分配时 zone 的优先级查找顺序)  |       |  |       |——> zoneref(作为 zonelist 的元素,指向具体 zone,用于在内存分配流程中引用 zone)  

内存分配的流程:
在内核进行内存分配时,通常按以下流程:

  1. 查找可用的 zone:内核先根据 zonelist 顺序查找可用的 zone
  2. 从 zone 获取页面:在选定的 zone 中查找空闲页面,若无空闲页面,可能触发慢路径(如回收页面)。
  3. 返回页面:找到空闲页面后,内核分配页面。

zone包含的内存类型:        

  1. 普通内存(ZONE_NORMAL)
    定义:普通内存区域是指可以直接被内核和用户程序访问的内存,通常涵盖物理内存地址空间中从低端开始的一段连续区域。
    特点:
    1. 访问速度相对较快,因直接映射到内核的线性地址空间。
    2. 适用于大部分内核数据结构和用户进程的数据存储。
    3. 在 32 位系统中,若未启用高端内存(ZONE_HIGHMEM),ZONE_NORMAL 可能占据大部分物理内存。
  2. DMA 区域(ZONE_DMA)
    定义:为满足设备进行 DMA(直接内存访问)操作而保留的内存区域。
    特点:
    1. 位于物理内存的较低地址部分,因一些老式 DMA 控制器只能访问物理内存的低地址区域(如 ISA 总线下的设备)。
    2. 区域大小通常较小,用于存储需通过 DMA 方式传输的数据(如网络数据包、磁盘数据等)。
    3. 确保设备可不经过 CPU 干预直接访问内存,提高数据传输效率。
  3. 高端内存(ZONE_HIGHMEM)
    定义:在 32 位系统中,因内核线性地址空间限制(通常仅 1GB 或 2GB 留给内核,取决于内核配置),物理内存超出内核线性地址空间能直接映射范围的部分。
    特点:
    1. 高端内存不能被内核直接访问,需通过特殊映射机制(如临时映射)访问。
    2. 在 64 位系统中,因线性地址空间充足,高端内存概念可能不再适用或重要性降低。
    3. 主要用于 32 位系统管理超出内核直接映射范围的物理内存。
  4. 可移动内存(ZONE_MOVABLE)
    定义:特殊内存区域,主要用于存放可移动的内存页。
    特点:
    1. 便于内存碎片整理,通过集中放置可移动内存页,整理时更易移动这些页,腾出连续物理内存空间。        
    2. 通常用于用户空间的匿名内存(如堆和栈),这些内存页必要时可移动到其他物理位置。
    3. 这些不同类型内存区域满足不同硬件和软件需求,确保系统高效、稳定运行。

在 Linux 内核中,通常一个内存节点(NUMA node,对应结构体 pglist_data)中的每个内存区域(zone)只会描述一个特定的内存类型(如 ZONE_NORMALZONE_DMAZONE_HIGHMEM 等)。因此,通常情况下,一个内存节点不会有多个相同类型的内存区域(比如两个 ZONE_NORMAL 或两个 ZONE_DMA 区域)。

为什么一个节点中只有一个 ZONE_NORMAL 或 ZONE_DMA

        在内核的内存管理中,内存区域(zone)用于区分不同类型的内存,这些内存类型的访问方式、大小和用途各不相同。例如:

  • ZONE_NORMAL:普通内存区域,用于应用程序内存分配,内核空间和用户空间均可使用。
  • ZONE_DMA:为 DMA(直接内存访问)设备保留的内存区域,这类设备通常只能访问低于特定物理地址的内存,需单独划分区域。
  • ZONE_HIGHMEM:高端内存区域,指超过内核线性地址空间限制的内存,主要用于 32 位系统。

        这些内存区域依内存物理地址范围、用途及硬件限制划分,每个区域有独立物理地址范围限制,因此一个物理内存节点通常只有一个 ZONE_NORMAL、一个 ZONE_DMA 和一个 ZONE_HIGHMEM 区域。

struct pglist_data 和 struct zone 之间的关系

        在 NUMA 架构中,每个内存节点(struct pglist_data)包含多个内存区域(struct zone)。例如,一个内存节点可能包含以下区域:

  • ZONE_NORMAL(普通内存)
  • ZONE_DMA(DMA 内存)
  • ZONE_HIGHMEM(高端内存)

        在此情况下,每个内存节点有一个 ZONE_NORMAL 区域、一个 ZONE_DMA 区域和一个 ZONE_HIGHMEM 区域,这些 zone 相互独立,分别描述不同内存类型。每个 struct zone 表示特定类型的内存区域,而非整个内存节点。

为什么不会有多个相同类型的 zone

内存区域(zone)基于物理内存特性划分,一个物理内存区域只能属于特定类型。例如:

  • ZONE_NORMAL:包含地址空间内大部分可用内存,是应用程序和内核的主要内存区域。
  • ZONE_DMA:针对 DMA 设备划分,包含低于特定物理地址的内存(如低于 1GB 或 4GB,取决于架构和硬件限制)。
  • ZONE_HIGHMEM:为超出内核虚拟地址空间限制的内存保留,常见于 32 位系统。

可能的例外情况

尽管一般情况下,每个内存节点只含一个特定类型的 zone,但以下情况可能导致变化:

  1. 区域类型调整:特定硬件配置或适配可能允许多个物理内存区域被视为一个逻辑区域,取决于硬件支持和内核实现。
  2. 动态调整:内核在内存分配管理中,可能通过区域划分调整、内存回收等机制动态调整或合并内存区域,但不意味着同一节点会有多个相同类型的 zone
  3. NUMA 节点间重叠:复杂硬件平台上,内存节点的物理地址空间可能重叠,导致节点共享内存区域。此时,内核可能处理区域合并或重映射,但每个节点内仍通常只有一个 ZONE_NORMAL、一个 ZONE_DMA 和一个 ZONE_HIGHMEM

3.物理页

        每个物理页对应一个 page 结构体,称为页描述符,内存节点的 pglist_data 实例的成员 node_mem_map 指向该内存节点包含的所有物理页的页描述符组成的数组。Linux 内核源码分析:include/linux/mm_types.h

        页是内存管理当中的最小单位,页面中的内存其物理地址是连续的,每个物理页由 struct page 描述。为了节省内存,struct page 是个联合体。

        页,又称为页帧,在内核当中,内存管理单元 MMU(负责虚拟地址和物理地址转换的硬件)是把物理页 page 作为内存管理的基本单位。体系结构不同,支持的页大小也相同。

        32 位体系结构支持 4kb 的页
        64 位体系结构支持 8kb 的页
        MIPS64 架构体系支持 16kb 的页。

https://github.com/0voice

相关文章:

Linux内核物理内存组织结构

一、系统调用sys_mmap 系统调用mmap用来创建内存映射,把创建内存映射主要的工作委托给do_mmap函数,内核源码文件处理:mm/mmap.c 二、系统调用sys_munmap 1、vma find_vma (mm, start); // 根据起始地址找到要删除的第一个虚拟内存区域 vma 2…...

【PostgreSQL内核学习:深入理解 PostgreSQL 中的 tuplesort_performsort 函数】

深入理解 PostgreSQL 中的 tuplesort_performsort 函数 函数概述函数源码函数签名核心功能相关函数简介 代码结构与逻辑分析1. 内存上下文切换2. 调试跟踪(可选)3. 状态机逻辑(switch 分支)4. 调试跟踪(完成时&#xf…...

谷歌 Gemini 2.5 Pro 免费开放

2025 年 3 月 30 日,谷歌宣布将最新的 Gemini AI 旗舰模型 Gemini 2.5 Pro 免费向所有 Gemini 应用用户开放。以下是关于此次免费开放的一些具体信息1: 背景:此前,Gemini 2.5 Pro 仅向支付 19.99 美元月费的 Gemini Advanced 用户…...

(多看) CExercise_05_1函数_1.2计算base的exponent次幂

题目: 键盘录入两个整数:底(base)和幂指数(exponent),计算base的exponent次幂,并打印输出对应的结果。(注意底和幂指数都可能是负数) 提示:求幂运算时,基础的思路就是先无脑把指数转…...

leetcode刷题 - 数组理论基础

数组是内存空间连续存储、相同类型数据的集合。遍历方式:下标索引 下标:从 0 开始 数组的元素不能删除,只能覆盖 定义一维数组: int arr0[10]; int arr1[10] { 100, 90,80,70,60,50,40,30,20,10 }; int arr2[ ] { 100,90,80,7…...

Jetpack Compose `ACTION_HOVER_EXIT` 事件异常解决方案

Jetpack Compose 1.6.6 版本中 ACTION_HOVER_EXIT 事件异常解决方案 问题现象 在 Android 应用开发中使用 Jetpack Compose 1.6.6 版本时,部分设备会出现以下崩溃日志: java.lang.IllegalStateException: The ACTION_HOVER_EXIT event was not cleare…...

Vuue2 element-admin管理后台,Crud.js封装表格参数修改

需求 表格数据调用列表接口,需要多传一个 Type字段,而Type字段的值 需要从跳转页面Url上面获取到,并赋值给Type,再传入列表接口中,最后拿到表格数据并展示 遇到的问题 需求很简单,但是因为表格使用的是统…...

Tiktok矩阵运营中使用云手机的好处

Tiktok矩阵运营中使用云手机的好处 云手机在TikTok矩阵运营中能够大幅提高管理效率、降低封号风险,并节省成本,是非常实用的运营工具。TikTok矩阵运营使用云手机有很多优势,特别是对于需要批量管理账号、提高运营效率的团队来说。以下是几个…...

Linux下调试器gdb_cgdb使用

文章目录 一、样例代码二、使用watchset var确定问题原因条件断点 一、样例代码 #include <stdio.h>int Sum(int s, int e) {int result 0;int i;for(i s; i < e; i){result i;}return result; }int main() {int start 1;int end 100;printf("I will begin…...

Vite环境下解决跨域问题

在 Vite 开发环境中&#xff0c;可以通过配置代理来解决跨域问题。以下是具体步骤&#xff1a; 在项目根目录下找到 vite.config.js 文件&#xff1a;如果没有&#xff0c;则需要创建一个。配置代理&#xff1a;在 vite.config.js 文件中&#xff0c;使用 server.proxy 选项来…...

超简单:Linux下opencv-gpu配置

1.下载opencv和opencv_contrib安装包 1&#xff09;使用命令下 git clone https://github.com/opencv/opencv.git -b 4.9.0 git clone https://github.com/opencv/opencv_contrib.git -b 4.9.02&#xff09;复制链接去GitHub下载然后上传到服务器 注意&#xff1a;看好版本&a…...

【matplotlib参数调整】

1. 基本绘图函数常用参数 折线图 import matplotlib.pyplot as plt import numpy as npx np.linspace(0, 10, 100) y np.sin(x)plt.plot(x, y, colorred, linestyle--, linewidth2,markero, markersize5, labelsin(x), alpha0.8) plt.title(折线图示例) plt.xlabel(X 轴) p…...

CSS语言的数据挖掘

数据挖掘与CSS语言的结合 引言 在现代社会&#xff0c;数据已然成为企业和个人决策的重要基础。通过有效的数据挖掘技术&#xff0c;能够从海量数据中提取出有价值的信息。在这个过程中&#xff0c;编程语言的选择至关重要。尽管CSS&#xff08;层叠样式表&#xff09;主要用…...

如何判断一条连接是TCP连接还是UDP连接?

在网络通信中&#xff0c;判断一条连接是UDP连接还是TCP连接&#xff0c;可以从协议特性、端口使用、应用场景以及抓包分析等方面入手&#xff1a; 1、基于协议头标志判断&#xff1a; TCP和UDP协议在网络层的头部信息存在差异。在实际的网络通信数据中&#xff0c;通过获取数…...

泰博云平台solr接口存在SSRF漏洞

免责声明&#xff1a;本号提供的网络安全信息仅供参考&#xff0c;不构成专业建议。作者不对任何由于使用本文信息而导致的直接或间接损害承担责任。如涉及侵权&#xff0c;请及时与我联系&#xff0c;我将尽快处理并删除相关内容。 漏洞描述 SSRF漏洞是一种在未能获取服务器…...

31天Python入门——第20天:魔法方法详解

你好&#xff0c;我是安然无虞。 文章目录 魔法方法1. __new__和__del__2. __repr__和__len__3. __enter__和__exit__4. 可迭代对象和迭代器5. 中括号[]数据操作6. __getattr__、__setattr__ 和 __delattr__7. 可调用的8. 运算符 魔法方法 魔法方法: Python中的魔法方法是一类…...

ubantu22.04中搭建地图开发环境(qt5.15.2 + osg3.7.0 + osgearth3.7.1 + osgqt)

一、下载安装qt5.15.2 二、下载编译安装osg3.7.0 三、下载编译安装osgearth3.7.1 四、下载编译安装osgqt 五、二三维地图显示demo开发 六、成果展示&#xff1a; 已有功能&#xff1a;加载了dom影像、可以进行二三维地图切换显示、二维地图支持缩放和平移、三维地图支持旋转…...

Linux驱动开发 块设备

目录 序言 1.块设备结构 分区(gendisk) 请求(request) 请求队列 1. 多队列架构 2. 默认限制与扩展 bio 2.块设备的使用 头文件与宏定义 blk-mq 相关结构和操作 块设备操作函数 模块初始化函数 模块退出函数 3.总结 序言 块设备&#xff08;如硬盘、虚拟盘&#x…...

简易Minecraft python

废话多说 以下是一个基于Python和ModernGL的简化版3D沙盒游戏框架。由于代码长度限制&#xff0c;这里提供一个核心实现&#xff08;约500行&#xff09;&#xff0c;您可以通过添加更多功能和内容来扩展它&#xff1a; python import pygame import moderngl import numpy a…...

Bethune X 6发布:为小规模数据库环境打造轻量化智能监控巡检利器

3月31日&#xff0c;“奇点时刻・数智跃迁 -- 云和恩墨2025春季产品发布会”通过视频号直播的方式在线上举办。发布会上&#xff0c;云和恩墨副总经理熊军正式发布 zCloud 6.7和zData X 3.3两款产品新版本&#xff0c;同时也带来了 Bethune X 6——这款面向小规模数据库环境的智…...

OpenCV 图形API(15)计算两个矩阵(通常代表二维向量的X和Y分量)每个对应元素之间的相位角(即角度)函数phase()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 描述 cv::gapi::phase 是 OpenCV 的 G-API 模块中的一个函数&#xff0c;用于计算两个矩阵&#xff08;通常代表二维向量的X和Y分量&#xff09;每个对应元…...

一文理解什么是中值模糊

目录 中值模糊的概念 中值模糊&#xff08;Median Blur&#xff09; 中值模糊的原理 示例&#xff1a;33 中值模糊 什么是椒盐噪声 椒盐噪声&#xff08;Salt-and-Pepper Noise&#xff09; 椒盐噪声的特点 OpenCV 中的 cv2.medianBlur() 函数格式 示例代码 中值模糊…...

游戏引擎学习第192天

仓库:https://gitee.com/mrxiao_com/2d_game_4 回顾 我们现在正在编写一些界面代码&#xff0c;主要是用户界面&#xff08;UI&#xff09;&#xff0c;不过这里的UI并不是游戏内的用户界面&#xff0c;而是为开发者设计的用户界面。我们正在尝试做一些小的UI元素&#xff0c…...

通信数据记录仪-产品概念ID

总结: 1、支持高速CAN、支持容错CAN、支持单线CAN(理解是支持不同的协议,CANFD、CAN2.0和LIN?) 2、 通过上位机设计时间...

Mac VM 卸载 win10 安装win7系统

卸载 找到相应直接删除&#xff08;移动到废纸篓&#xff09; 可参考&#xff1a;mac如何卸载虚拟机win 下载 win7下载地址...

基于图扑 HT 技术的电缆厂 3D 可视化管控系统深度解析

在当今数字化浪潮席卷制造业的大背景下&#xff0c;图扑软件&#xff08;Hightopo&#xff09;凭借其自主研发的强大技术&#xff0c;为电缆厂打造了一套先进的 3D 可视化管控系统。该系统基于 HT for Web 技术&#xff0c;为电缆厂的数字化转型提供了有力支撑。 HT 技术核心架…...

《AI大模型开发笔记》MCP快速入门实战(一)

目录 1. MCP入门介绍 2. Function calling技术回顾 3. 大模型Agent开发技术体系回顾 二、 MCP客户端Client开发流程 1. uv工具入门使用指南 1.1 uv入门介绍 1.2 uv安装流程 1.3 uv的基本用法介绍 2.MCP极简客户端搭建流程 2.1 创建 MCP 客户端项目 2.2 创建MCP客户端…...

C++多态:从青铜九鼎到虚函数表的千年演化密码

一、青铜礼器中的多态启示——九鼎的形与神 在故宫博物院深处&#xff0c;九尊青铜鼎静静矗立。这些跨越三千年的礼器&#xff0c;表面斑驳的铜锈下隐藏着惊人的铸造工艺&#xff1a;鼎足采用分铸法预制&#xff0c;器身主体采用浑铸法一次成型&#xff0c;纹饰运用浮雕与阴刻…...

【愚公系列】《高效使用DeepSeek》051-产品创新研发

🌟【技术大咖愚公搬代码:全栈专家的成长之路,你关注的宝藏博主在这里!】🌟 📣开发者圈持续输出高质量干货的"愚公精神"践行者——全网百万开发者都在追更的顶级技术博主! 👉 江湖人称"愚公搬代码",用七年如一日的精神深耕技术领域,以"…...

常见的ETL工具分类整理

一、开源ETL工具 ‌Kettle&#xff08;Pentaho Data Integration&#xff09;--Spoon‌ 设计及架构&#xff1a;面向数据仓库建模的传统ETL工具。使用方式&#xff1a;C/S客户端模式&#xff0c;开发和生产环境需要独立部署&#xff0c;任务编写、调试、修改都在本地。底层架构…...