linux物理内存管理:node,zone,page
一、总览
对于物理内存内存,linux对内存的组织逻辑从上到下依次是:node,zone,page,这些page是根据buddy分配算法组织的,看下面两张图:



上面的概念做下简单的介绍:
- Node:每个CPU下的本地内存节点就是一个Node,如果是UMA架构下,就只有一个Node0,在NUMA架构下,会有多个Node
- Zone:每个Node会划分很多域Zone,大概有下面这些:
- ZONE_DMA:定义适合DMA的内存域,该区域的长度依赖于处理器类型。比如ARM所有地址都可以进行DMA,所以该值可以很大,或者干脆不定义DMA类型的内存域。而在IA-32的处理器上,一般定义为16M。
- ZONE_DMA32:只在64位系统上有效,为一些32位外设DMA时分配内存。如果物理内存大于4G,该值为4G,否则与实际的物理内存大小相同。
- ZONE_NORMAL:定义可直接映射到内核空间的普通内存域。在64位系统上,如果物理内存小于4G,该内存域为空。而在32位系统上,该值最大为896M。
- ZONE_HIGHMEM:只在32位系统上有效,标记超过896M范围的内存。在64位系统上,由于地址空间巨大,超过4G的内存都分布在ZONE_NORMA内存域。
- ZONE_MOVABLE:伪内存域,为了实现减小内存碎片的机制。
- 分配价值链
- 除了只能在某个区域分配的内存(比如ZONE_DMA),普通的内存分配会有一个“价值”的层次结构,按分配的“廉价度”依次为:ZONE_HIGHMEM > ZONE_NORMAL > ZONE_DMA。
- 即内核在进行内存分配时,优先从高端内存进行分配,其次是普通内存,最后才是DMA内存
- Page:zone下面就是真正的内存页了,每个页基础大小是4K,他们维护在一个叫free_area的数组结构中
- order:数组的index,也叫order,实际对应的是page的大小,比如order为0,那么就是一堆1个空闲页(4K)组成的链表,order为1,就是一堆2个空闲页(8K)组成的链表,order为2,就是一堆4个空闲页(16K)组成的链表
二、源码分析
内存节点结构体在linux内核include/linux/mmzone.h文件
| level | struct | desc |
|---|---|---|
| node | struct pglist_data | NUMA下每个node由一个pglist_data结构体描述 UMA下只有一个node,即全局变量 |
| zone | struct zone | 每个node下的物理内存被划分为不同zone,体现不同用途。整个系统里可能只有几个struct zone。 |
| page | struct page | 描述每个物理页(page frame)的结构,每个物理页都有一个struct page,寸土寸金。 |
2.1、 struct pglist_data
mmzone.h - include/linux/mmzone.h - Linux source code v5.4.285 - Bootlin Elixir Cross Referencer
每个NUMA node对应一个struct pglist_data结构体,一些重要成员有:
| name | type | desc |
|---|---|---|
| node_zones | struct zone数组,长度为MAX_NR_ZONES | 该node下的zone。数组长度虽然是MAX_NR_ZONES,但是不代表当前node的实际zone数目就是MAX_NR_ZONES。实际的数量用nr_zones表示 |
| node_zonelists | struct zonelist数组,长度为MAX_ZONELISTS | 内存分配器在分配内存时,按照一定的策略遍历不同的内存区域,以找到合适的内存块。不同的内存区域可能有不同的属性(dma,normal,high等),node_zonelists帮助内存分配器根据需求选择合适的区域 |
| nr_zones | int | 该node下实际zone的数量 |
| node_start_pfn | unsigned long long | node的起始pfn号,起始的物理地址 |
| node_present_pages | unsigned long long | node实际包括的page数目(不含空洞) |
| node_spanned_pages | unsigned long long | node横跨的page数目(包括空洞) |
| kswapd | struct task_struct * | 每个node都有一个kswapd线程,用于回收不经常使用的页面或者内存不足时回收内存 |
| kswapd_wait | struct wait_queue_head | kswapd_wait表示是一个kswapd等待队列,里面存放的是等待kswapd线程执行异步回收的线程,在free_area_init_core 函数中被初始化。 |
| pfmemalloc_wait | struct wait_queue_head | 表示等待直接内存回收(direct reclaim)结束的线程等待队列。里面存放的都是等待由kswapd帮忙做完直接内存回收的线程。当kswapd直接内存回收后,整个node的free pages满足要求时,在kswapd睡眠前,kswapd会唤醒pfmemalloc_wait里面的线程,线程直接进行内存分配,这个等待队列的线程跳过了自己direct reclaim的操作。 |
| kswapd_order | int | 表示kswapd线程内存回收的单位(2^kswapd_order),要求大于线程内存分配所需求的order,否则会更新为线程内存分配对应的order。 |
| node_mem_map; | struct page * | 当前node中所有struct page构成的mem_map数组 |
常见的zone类型有:
- ZONE_DMA,一些设备地址线数目有限(如24位),进行DMA时只能使用低地址(如<16MB),划分出ZONE_DMA防止低地址的页被分出去导致设备无法进行DMA。
- ZONE_DMA32,64位系统下,区分支持32位地址线和24位地址线的DMA设备。
- ZONE_NORMAL,一般内存处于这个zone区域。
- ZONE_HIGHMEM,32位系统虚拟地址空间太小,只有1G给内核态,因此只能映射最多1G物理内存。高端内存区用于建立到物理地址的临时映射,使内核态可以寻址更多物理地址。64位架构下虚拟地址空间足够大,不需要这个zone。
enum zone_type {
#ifdef CONFIG_ZONE_DMA/** ZONE_DMA is used when there are devices that are not able* to do DMA to all of addressable memory (ZONE_NORMAL). Then we* carve out the portion of memory that is needed for these devices.* The range is arch specific.** Some examples** Architecture Limit* ---------------------------* parisc, ia64, sparc <4G* s390, powerpc <2G* arm Various* alpha Unlimited or 0-16MB.** i386, x86_64 and multiple other arches* <16M.*/ZONE_DMA,
#endif
#ifdef CONFIG_ZONE_DMA32/** x86_64 needs two ZONE_DMAs because it supports devices that are* only able to do DMA to the lower 16M but also 32 bit devices that* can only do DMA areas below 4G.*/ZONE_DMA32,
#endif/** Normal addressable memory is in ZONE_NORMAL. DMA operations can be* performed on pages in ZONE_NORMAL if the DMA devices support* transfers to all addressable memory.*/ZONE_NORMAL,
#ifdef CONFIG_HIGHMEM/** A memory area that is only addressable by the kernel through* mapping portions into its own address space. This is for example* used by i386 to allow the kernel to address the memory beyond* 900MB. The kernel will set up special mappings (page* table entries on i386) for each page that the kernel needs to* access.*/ZONE_HIGHMEM,
#endifZONE_MOVABLE,
#ifdef CONFIG_ZONE_DEVICEZONE_DEVICE,
#endif__MAX_NR_ZONES};
2.2、 struct zone
mmzone.h - include/linux/mmzone.h - Linux source code v5.4.285 - Bootlin Elixir Cross Referencer
zone通过pfn和一些计数器描述它管理的物理地址空间:
zone_start_pfn,该zone所描述空间的起始页号。spanned_pages,整个空间(包括空洞)占据的物理页数目,它等于zone_end_pfn - zone_start_pfn。present_pages,存在于空间中的物理页数目,等于spanned_pages减掉空洞中的页数目。managed_pages,被buddy system管理的页数目,等于present_pages减掉被zone预留做其他用途的页数目。struct free_area free_area[MAX_ORDER],buddy system使用的空闲链表,是一个per zone的结构。它直接存储了指向struct page*的指针。(详细见:伙伴(buddy)系统原理_伙伴系统算法-CSDN博客)- unsigned long _watermark[NR_WMARK]:内存水位值,分别为WMARK_MIN, WMARK_LOW, WMARK_HIGH水位,这在页面分配器和kswapd页面回收中会用到。
- long lowmem_reserve[MAX_NR_ZONES]:zone中预留的内存。在内存分配时,高区的内存不足可以向低区的内存申请。reserve内存是确保在内存紧张的时候,仍然保留一定数量的低区内存,确保高区内存不会完全耗尽低区内存资源。
2.3、 struct page
mm_types.h - include/linux/mm_types.h - Linux source code v5.4.285 - Bootlin Elixir Cross Referencer
这是一个特别复杂的结构,里面有很多的 union,这里之所以用了 union,是因为一个物理页面使用模式有两种。第一种模式,仅需分配小块内存,Linux 系统采用了一种被称为 slab allocator的技术。第二种模式,要用就用一整页。这一整页的内存,或者直接和虚拟地址空间建立映射关系,我们把这种称为匿名页(Anonymous Page)。或者用于关联一个文件,然后再和虚拟地址空间建立映射关系,这样的文件,我们称为内存映射文件(Memory-mapped File)。
每个物理页对应一个page结构体,称为页描述符,内存节点的pglist_data实例的成员node_mem_map指向该内存节点包含的所有物理页的页描述符组成的数组。
一些重要成员有:
| name | type | desc |
| flags | unsigned long | enum pgdat_flags 可以指示节点的状态或特定的内存管理属性。以便在内存分配、回收和其他操作中做出相应的决策。 以下是一些常见的 pgdat_flags 标志: PGDAT_CONGESTED:表示该节点的内存可能处于拥塞状态。 PGDAT_WRITEBACK:表示该节点的内存正在进行写回操作。 PGDAT_RECLAIM_LOCKED:表示该节点的内存回收操作被锁定。 |
三、建立与初始化过程
ref:
Linux内存管理-1 | Do not touch fish!
Linux内存初始化(3)——pglist_data/zone初始化_linux struct page结构初始化-CSDN博客
Linux 物理内存管理涉及的三大结构体之struct pglist_data_linux的三种内存模型-CSDN博客
相关文章:
linux物理内存管理:node,zone,page
一、总览 对于物理内存内存,linux对内存的组织逻辑从上到下依次是:node,zone,page,这些page是根据buddy分配算法组织的,看下面两张图: 上面的概念做下简单的介绍: Node:…...
uniapp 设置安全区域
<!-- 获取安全区域 --> <script setup lang"ts"> import { computed, ref } from vuelet systemType ref(1) // #ifdef APP-PLUS || H5 || APP-PLUS-NVUE systemType.value 1 const { safeAreaInsets } uni.getSystemInfoSync() console.log(safeAre…...
渐进式JavaScript框架Vue 3 入门
目录 前言1. Vue 3 的基础入门1.1 什么是 Vue.js1.2 局部使用 Vue 2. Vue 3 的基本配置2.1 准备 HTML 页面并引入 Vue 模块2.2 创建 Vue 应用实例 3. Vue 的数据绑定与界面渲染3.1 插值表达式 4. 常用指令详解4.1 v-for 指令:列表渲染4.2 v-bind 指令:绑…...
【真题笔记】21年系统架构设计师案例理论点总结
【真题笔记】21年系统架构设计师案例理论点总结 从机器学习定义的灵活性和学习算法的可扩展性,对解释器+管道过滤器+隐式调用进行对比分析!面向对象方法开发软件,建立对象模型+动态模型+功能模型,三者关联关系!数据架构的设计过程包括:数据定义、数据分布、数据管理,三者…...
PostgreSQL的奥秘:深入探究事务与锁的秘密世界
PostgreSQL事务 1. 概述 在数据库系统中,事务(Transaction)是执行数据库操作的最小逻辑单位。它确保了一组操作的完整性和一致性。事务可以通过显式的 BEGIN、COMMIT 和 ROLLBACK 语句块来控制,也可以在自动提交模式(…...
Python进行GRPC和Dubbo协议的高级测试
在微服务架构日益流行的今天,分布式系统的复杂性不断增加。GRPC 和 Dubbo 协议作为当今互联网行业中常见的高性能通信协议,已经成为服务之间交互的核心。然而,随着服务调用层次的不断增加,如何有效地测试这两种协议,确…...
全程云OA系统QCPES.asmx存在SQL注入漏洞
免责声明: 本文旨在提供有关特定漏洞的深入信息,帮助用户充分了解潜在的安全风险。发布此信息的目的在于提升网络安全意识和推动技术进步,未经授权访问系统、网络或应用程序,可能会导致法律责任或严重后果。因此,作者不对读者基于本文内容所采取的任何行为承担责任。读者在…...
从建立TRUST到实现FAIR:可持续海洋经济的数据管理
1. 引言 随着我们对信息管理方式的信任,我们的社会对数字化数据的以来呈指数级增长。为了跟上大数据的需求,通过不断的努力和持续实践,对“good”数据管理方式的共识也在不断发展和演变。 加拿大正在建设国家基础设施和服务以及研究数据管理…...
基于SSM的“汽车销售分析与管理系统”的设计与实现(源码+数据库+文档+PPT)
基于SSM的“汽车销售分析与管理系统”的设计与实现(源码数据库文档PPT) 开发语言:Java 数据库:MySQL 技术:SSM 工具:IDEA/Ecilpse、Navicat、Maven 系统展示 系统功能结构图 销售经理系统首页图 客户管理图 车辆销…...
vs2015QT项目添加多语言翻译总结
一、简介 当软件有国际化的需求时,就需要多语言翻译功能,最常见的语言就是支持中文和英语,本文介绍在vs2015QT环境下,进行国际化翻译的具体流程。 二、多语言翻译实现流程 1.底层实现原理介绍 QT写的客户端软件,能…...
替换OpenTSDB和HBase,宝武集团使用IoTDB助力钢铁设备智能运维
时序数据库 IoTDB 应用于宝武集团全基地钢铁时序数据管理,激活数据资产,赋能大型设备智能运维。 1. 背景概述 宝武装备智能科技有限公司(以下简称:宝武智维)是中国宝武设备智能运维专业化平台公司,30 余年始…...
MathGPT的原理介绍,在中小学数学教学的应用场景,以及代码样例实现
大家好,我是微学AI,今天给大家介绍一下MathGPT的原理介绍,在中小学数学教学的应用场景,以及代码样例实现。MathGPT的核心架构是一个精心设计的多层次系统,旨在有效处理复杂的数学问题。其主要组成部分包括 数学知识图谱…...
前端框架大比拼:React.js, Vue.js 及 Angular 的优势与适用场景探讨
文章目录 前言一、React.js特点使用方法适用场景 二、Vue.js特点使用方法适用场景 三、Angular特点使用方法适用场景 四、如何选择合适的前端框架五、前端框架对项目性能的影响结语 前言 随着互联网技术的飞速发展,前端开发已经从简单的页面展示演变为复杂的应用构…...
MySQL45讲 第二十讲 幻读是什么,幻读有什么问题?
文章目录 MySQL45讲 第二十讲 幻读是什么,幻读有什么问题?一、幻读的定义二、幻读带来的问题(一)语义问题(二)数据一致性问题 三、InnoDB 解决幻读的方法四、总结 MySQL45讲 第二十讲 幻读是什么࿰…...
MySQL技巧之跨服务器数据查询:进阶篇-从A数据库复制到B数据库的表中
MySQL技巧之跨服务器数据查询:进阶篇-从A数据库复制到B数据库的表中 基础篇已经描述:借用微软的SQL Server ODBC 即可实现MySQL跨服务器间的数据查询。 而且还介绍了如何获得一个在MS SQL Server 可以连接指定实例的MySQL数据库的连接名: MY_ODBC_MYSQ…...
【论文阅读】利用SEM二维图像表征黏土矿物三维结构
导言 在油气储层研究中,黏土矿物对流体流动的影响需要在微观尺度上理解,但传统的二维SEM图像难以完整地表征三维孔隙结构。常规的三维成像技术如FIB-SEM(聚焦离子束扫描电子显微镜)虽然可以获取高精度的3D图像,但成本…...
可靠UDP协议(KCP)使用说明
希望这篇文章,对学习和使用 KCP 协议的读者,有帮助。 1. KCPUDP 流程图 2. 示例代码(待补充) #include <iostream>int main() {// TODO: kcp examplereturn 0; }...
ffmpeg+D3D实现的MFC音视频播放器,支持录像、截图、音视频播放、码流信息显示等功能
一、简介 本播放器是在vs2019下开发,通过ffmpeg实现拉流解码功能,通过D3D实现视频的渲染功能。截图功能采用libjpeg实现,可以截取jpg图片,图片的默认保存路径是在C:\MYRecPath中。录像功能采用封装好的类Mp4Record实现,…...
【Flink】-- flink新版本发布:v2.0-preview1
目录 1、简介 2、非兼容变更 2.1、API 2.2、连接器适配计划 2.3、配置 2.4、其它 3、重要新特性 3.1、存算分离状态管理 3.2、物化表 3.3、批作业的自适应执行 3.4、流式湖仓 4、附加 4.1、非兼容性的 api 程序变更 4.1.2、Removed Classes # 4.1.3、Modified Cl…...
Node.js 版本管理的最终答案 Volta
文章目录 特点安装Unix系统安装Windows系统安装 常用命令volta fetchvolta installvolta uninstallvolta pinvolta listvolta completionsvolta whichvolta setupvolta runvolta help 建议 目前对于前端项目的node 版本,我们一般会在项目 package.json 的 engines 字…...
Spring Boot 实现流式响应(兼容 2.7.x)
在实际开发中,我们可能会遇到一些流式数据处理的场景,比如接收来自上游接口的 Server-Sent Events(SSE) 或 流式 JSON 内容,并将其原样中转给前端页面或客户端。这种情况下,传统的 RestTemplate 缓存机制会…...
Python实现prophet 理论及参数优化
文章目录 Prophet理论及模型参数介绍Python代码完整实现prophet 添加外部数据进行模型优化 之前初步学习prophet的时候,写过一篇简单实现,后期随着对该模型的深入研究,本次记录涉及到prophet 的公式以及参数调优,从公式可以更直观…...
【Go语言基础【12】】指针:声明、取地址、解引用
文章目录 零、概述:指针 vs. 引用(类比其他语言)一、指针基础概念二、指针声明与初始化三、指针操作符1. &:取地址(拿到内存地址)2. *:解引用(拿到值) 四、空指针&am…...
【MATLAB代码】基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),附源代码|订阅专栏后可直接查看
文章所述的代码实现了基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),针对传感器观测数据中存在的脉冲型异常噪声问题,通过非线性加权机制提升滤波器的抗干扰能力。代码通过对比传统KF与MCC-KF在含异常值场景下的表现,验证了后者在状态估计鲁棒性方面的显著优…...
Elastic 获得 AWS 教育 ISV 合作伙伴资质,进一步增强教育解决方案产品组合
作者:来自 Elastic Udayasimha Theepireddy (Uday), Brian Bergholm, Marianna Jonsdottir 通过搜索 AI 和云创新推动教育领域的数字化转型。 我们非常高兴地宣布,Elastic 已获得 AWS 教育 ISV 合作伙伴资质。这一重要认证表明,Elastic 作为 …...
自然语言处理——文本分类
文本分类 传统机器学习方法文本表示向量空间模型 特征选择文档频率互信息信息增益(IG) 分类器设计贝叶斯理论:线性判别函数 文本分类性能评估P-R曲线ROC曲线 将文本文档或句子分类为预定义的类或类别, 有单标签多类别文本分类和多…...
pgsql:还原数据库后出现重复序列导致“more than one owned sequence found“报错问题的解决
问题: pgsql数据库通过备份数据库文件进行还原时,如果表中有自增序列,还原后可能会出现重复的序列,此时若向表中插入新行时会出现“more than one owned sequence found”的报错提示。 点击菜单“其它”-》“序列”,…...
Qt Quick Controls模块功能及架构
Qt Quick Controls是Qt Quick的一个附加模块,提供了一套用于构建完整用户界面的UI控件。在Qt 6.0中,这个模块经历了重大重构和改进。 一、主要功能和特点 1. 架构重构 完全重写了底层架构,与Qt Quick更紧密集成 移除了对Qt Widgets的依赖&…...
统计学(第8版)——统计抽样学习笔记(考试用)
一、统计抽样的核心内容与问题 研究内容 从总体中科学抽取样本的方法利用样本数据推断总体特征(均值、比率、总量)控制抽样误差与非抽样误差 解决的核心问题 在成本约束下,用少量样本准确推断总体特征量化估计结果的可靠性(置…...
npm安装electron下载太慢,导致报错
npm安装electron下载太慢,导致报错 背景 想学习electron框架做个桌面应用,卡在了安装依赖(无语了)。。。一开始以为node版本或者npm版本太低问题,调整版本后还是报错。偶尔执行install命令后,可以开始下载…...
