【Linux 内核 内存管理】物理内存组织结构

news2024/11/19 1:50:38

一、 UMA和NUMA两种模型
共享存储型多处理机有两种模型
一致内存访问(Uniform-Memory-Access,简称UMA)模型

非一致内存访问(Nonuniform-Memory-Access,简称NUMA)模型

UMA模型
物理存储器被所有处理器件均匀共享。所有处理机对所有存储字具有相同的存取时间,这就是为什么称它为均匀存储器存取的原因。每台处理机可以有私用高速缓存,外围设备也以一定形式共享。
在这里插入图片描述

NUMA模型
NUMA模式下,处理器被划分成多个”节点”(node), 每个节点被分配有的本地存储器空间。 所有节点中的处理器都可以访问全部的系统物理存储器,但是访问本节点内的存储器所需要的时间,比访问某些远程节点内的存储器所花的时间要少得多。
在这里插入图片描述
Linux适用于各种不同的体系结构, 而不同体系结构在内存管理方面的差别很大. 因此linux内核需要用一种体系结构无关的方式来表示内存。
在 NUMA 非一致内存访问架构 中, 将 CPU 划分为多个节点 , 每个节点都有自己的 " 内存控制器 " 和 " 内存插槽 " , CPU 访问自己的节点上的 内存 很快 , 但是访问其它 CPU 的内存 很慢 ;
在UMA结构下, 则任务系统中只存在一个内存node, 这样对于UMA结构来说, 内核把内存当成只有一个内存node节点的伪NUMA。

注意:NUMA 内存节点分为两种情况

  • 根据 " 处理器与内存的距离 " 划分 " 内存节点 " ;
  • 在 不连续内存 的 NUMA 架构中 , 根据 " 物理地址是否连续 " 划分 " 内存节点 " , 每个 物理地址连续 的内存块 是一个 " 内存节点 " ;

二、内存管理系统 3 级结构

① 节点 Node ,
② 区域 Zone ,
③ 页 Page ,
Linux 内核中 , 使用 上述 3级结构 描述 和 管理 " 物理内存 " ;

2.1 内存节点 pglist_data 结构体
Linux 内核中 , 使用 pglist_data 结构体 描述 " 内存节点 " , 该结构体定义在 Linux 内核源码中的 linux-4.12\include\linux\mmzone.h#601 位置 ;
其中 :
node_zones 是 内存区域数组 ;

struct zone node_zones[MAX_NR_ZONES];

node_zonelists 是 备用区域列表 ;

struct zonelist node_zonelists[MAX_ZONELISTS];

nr_zones 是 该 " 内存节点 " 包含 多少个 " 内存区域 " ;

// 该 " 内存节点 " 包含 多少个 " 内存区域 "
int nr_zones;

CONFIG_FLAT_NODE_MEM_MAP 宏定义指的是 " 除 稀疏内存模型 之外 " 的情况 , 该情况下 声明 struct page *node_mem_map 页描述数组 ;
struct page_ext *node_page_ext 是 内存页的扩展属性 ;

#ifdef CONFIG_FLAT_NODE_MEM_MAP	/* means !SPARSEMEM */
	// 页描述数组
	struct page *node_mem_map;
#ifdef CONFIG_PAGE_EXTENSION
	// 内存页的扩展属性
	struct page_ext *node_page_ext;
#endif
#endif

node_start_pfn 是 该 " 内存节点 " 的 起始物理页 编号 ;
node_present_pages 是 物理页 的总数 ;
node_spanned_pages 是 物理页 的区间范围 总大小 , 该大小包括 " 内存空洞 " 大小 ;
node_id 是 节点标识符 ;

2.2 内存区域 zone 简介
" 内存节点 " 再向下划分 , 就是 " 内存区域 " zone ,
" 内存区域 " 在 Linux 内核中使用 struct zone 结构体类型进行描述 , zone 枚举定义在 Linux 内核源码的 linux-4.12\include\linux\mmzone.h#350 位置 ;

enum zone_type {
#ifdef CONFIG_ZONE_DMA
    //如果一些设备不能直接访问所有内存,需要使用DMA内存,例如ISA总线只能直接访问16MB以下的内存.不需要通过MMU管理,连续分配,具有更高的性能
	ZONE_DMA,
#endif
#ifdef CONFIG_ZONE_DMA32
    //标记了使用32位地址可寻址、适合DMA的内存域,显然只有64位系统上,才会有该内存域。
	ZONE_DMA32,
#endif
    //可以直接映射到内核段的普通内存域,这是所有体系机构上保证都会存在的唯一内存域,在IA-32系统上,该域可访问的最大内存不超过896MiB,超过该值的内存只能能通过高端内存寻址访问ZONE_HIGHMEM中的内存。
	ZONE_NORMAL,
#ifdef CONFIG_HIGHMEM
   //超出了内核段的物理内存。只有在可用物理内存多余可映射的内核内存时,才会访问该域,显然一般只有32位系统上才会有可能有该区域。通过kmap及kunmap将该域内存映射到内核虚拟地址空间。
	ZONE_HIGHMEM,
#endif
//伪内存区域,用来防止内存区域
	ZONE_MOVABLE,
#ifdef CONFIG_ZONE_DEVICE
//为了支持持久内存热拔插增加的内存区域,每个内存区域用一个zone结构体控制
	ZONE_DEVICE,
#endif
	__MAX_NR_ZONES

};

ZONE的数据结构如下:

struct zone {
    unsigned long _watermark[NR_WMARK];
    unsigned long watermark_boost;
 
    unsigned long nr_reserved_highatomic;
    long lowmem_reserve[MAX_NR_ZONES];
    const char      *name;
    struct free_area    free_area[MAX_ORDER];
    unsigned long       flags;
}
  • 水位: 每个zone都有三个水位值
    WMARK_MIN: 最低水位,代表内存显然已经不够用了。
    WMARK_LOW:低水位,代表内存已经开始吃紧,需要启动回收页内核线性kswapped去回收内存
    WMARK_HIGH:高水位,代表内存还是足够的。
enum zone_watermarks {
    WMARK_MIN,
    WMARK_LOW,
    WMARK_HIGH,
    NR_WMARK
};
  • lowmem_reserve: 这个zone区域保留的内存,当系统内存出现不足的时候,系统就会使用这些保留的内存来做一些操作,比如使用保留的内存进程用来可以释放更多的内存
  • free_area:用于维护空闲的页,其中数组的下标对应页的order数。最大order目前是11,free_are的结构体。
struct free_area {
    struct list_head    free_list[MIGRATE_TYPES];
    unsigned long       nr_free;
};
  • free_list:用于将各个order的free page链接在一起
  • nr_free: 代表这个order中还有多个空闲page
    而每一个order中又根据迁移类型分成了几组。
enum migratetype {
    MIGRATE_UNMOVABLE,
    MIGRATE_MOVABLE,
    MIGRATE_RECLAIMABLE,
#ifdef CONFIG_CMA
    MIGRATE_CMA,
#endif
    MIGRATE_PCPTYPES, /* the number of types on the pcp lists */
    MIGRATE_HIGHATOMIC = MIGRATE_PCPTYPES,
#ifdef CONFIG_MEMORY_ISOLATION
    MIGRATE_ISOLATE,    /* can't allocate from here */
#endif
    MIGRATE_TYPES
};
MIGRATE_UNMOVABLE: 不可移动的页
MIGRATE_MOVABLE:可以移动的页,当出现内存碎片的时候,就可以移动此页,腾出更多连续的空间
MIGRATE_RECLAIMABLE:可以回收的页
MIGRATE_CMA:用于专门CMA申请的页
MIGRATE_PCPTYPES:per-cpu的使用的
MIGRATE_HIGHATOMIC:高阶原子分配
MIGRATE_ISOLATE:隔离,不能从此分配页

在这里插入图片描述
可以通过我当前的设备,查看page的信息cat /proc/pagetypeinfo
在这里插入图片描述
可以很清晰的看到各个order中不同类型,不同zone,page的剩余情况。当然也可以从cat /proc/buddyinfo看各个page的剩余情况。
当然了我们的zone,也可以通过cat /proc/zoneinfo去查看zone的详细信息的。

root:/ # cat /proc/zoneinfo
Node 0, zone   Normal
  pages free     126204
        min      1251
        low      9254
        high     9566
        spanned  1308544
        present  1180543
        managed  1136476
        protection: (0, 24576)
      nr_free_pages 126204
      nr_zone_inactive_anon 984
      nr_zone_active_anon 61238
      nr_zone_inactive_file 423539
      nr_zone_active_file 122889
      nr_zone_unevictable 987
      nr_zone_write_pending 288
      nr_mlock     987
      nr_page_table_pages 13969
      nr_kernel_stack 36784
      nr_bounce    0
      nr_zspages   0
      nr_free_cma  60532
Node 0, zone  Movable
  pages free     680267
        min      866
        low      6404
        high     6620
        spanned  786432
        present  786432
        managed  786432
        protection: (0, 0)
      nr_free_pages 680267
      nr_zone_inactive_anon 0
      nr_zone_active_anon 104777
      nr_zone_inactive_file 0
      nr_zone_active_file 0
      nr_zone_unevictable 121
      nr_zone_write_pending 0
      nr_mlock     121
      nr_page_table_pages 0
      nr_kernel_stack 0
      nr_bounce    0
      nr_zspages   0
      nr_free_cma  0

2.3 物理页
每个物理页对应一个page结构体,称为页描述符。内存节点的pglist_data实例的成员node_mem_map指向该内存节点包含的所有物理页的页描述符组成的数组。
页是内存管理中的最小单位,页面中的内存其物理地址是连续的,每个物理页由struct page描述。为了节省内存,struct page是一个联合体。
页,又称为页帧,在内核当中,内存管理单元MMU(负责虚拟地址和物理地址转换的硬件)是把物理页page作为内存管理的基本单位。体系结构不同,支持的页大小也相同。
32位体系结构支持4kb的页;64位体系结构支持8kb的页;MIPS64架构体系支持16kb的页。
Linux内核源码分析:include/linux/mm_types.h

struct page {
	unsigned long flags;//原子标志,有些情况下会异步更新
 
	union {
		struct {	/* Page cache and anonymous pages */
			struct list_head lru;
			//如果最低位位0,则指向inode address_space 或为NULL
			//如果页映射为匿名地址,最低位置位,而且指针指向anon_vma对象
			struct address_space *mapping;
			pgoff_t index;		/* Our offset within mapping. */
 
			//由映射私有,不透明数据;
			//如果设置了PagePrivate,通常用于buffer_heads,
			//如果设置了PageSwapCache,则用于swp_entry_t
			//如果设置了PageBuddy 则用于伙伴系统中的阶
			unsigned long private;
		};
 
		struct {	/* slab, slob and slub */
			union {
				struct list_head slab_list;
				struct {	/* Partial pages */
					struct page *next;
#ifdef CONFIG_64BIT
					int pages;	/* Nr of pages left */
					int pobjects;	/* Approximate count */
#else
					short int pages;
					short int pobjects;
#endif
				};
			};
			struct kmem_cache *slab_cache; /* not slob */
			/* Double-word boundary */
			void *freelist;		/* first free object */
			union {
				void *s_mem;	/* slab: first object */
				unsigned long counters;		/* SLUB */
				struct {			/* SLUB */
					unsigned inuse:16;
					unsigned objects:15;
					unsigned frozen:1;
				};
			};
		};
...
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/107029.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

超标量处理器设计——第八章_发射

超标量处理器设计——第八章_发射 参考《超标量处理器》姚永斌著 文章目录超标量处理器设计——第八章_发射8.1 简述8.1.1 集中式 VS. 分布式8.1.2 数据捕捉 VS. 非数据捕捉8.1.3 压缩 VS. 非压缩8.2 发射过程的流水线8.2.1 非数据捕捉结构的流水线8.2.2 数据捕捉结构的流水线8…

随手写系列——写一个凯撒密码转换页面

文章目录先展示效果H5编写C3编写JS编写——方法一:过程版JS编写——方法二:对象版代码获取先展示效果 (因为主要是实现功能,所以CSS写的很粗糙) H5编写 基础结构如下: 先构成最外面的大盒子.box&#…

【Flutter】之便于提高开发效率的周边库和轮子

GetX 状态管理 GetX包含很多功能,各种弹出widget、路由管理、国际化、Utils、状态管理等。 基于路由管理 1. 添加到项目中 1.1. 将此添加到pubspec.yaml文件中。 get: 4.1.4 1.2. 在命令行中运行 flutter packages get 1.3. 在MaterialApp前面加上 “Get”&…

centos7 yum安装postgreSQL

安装环境centos7.6 安装步骤: 1、安装postgresql: yum install postgresql-server 2、安装postgresql 扩展包: yum install postgresql-contrib 3、初始化: postgresql-setup initdb 4、启动开机自启动: systemc…

说话人识别神经网络推理方式

概述 说话人识别是一个序列总结(Sequence Summarization)任务,输入是音频(或者说,声学特征的序列),输出是说话人的嵌入码,有的神经网络可以输入一对音频,直接输出这对音…

java微信支付v3系列——9.微信支付之商家转账API

这个功能就比较复杂了,首先是得有90天的资金流水才能开通,其次开通后还需要在官网进行配置,不能直接调用,并且限制了IP地址。 如下图所示,首先需要进行产品设置,将里面都设置好后才能进行开发,…

feign 调用常见问题避坑指南!

摘要:主要是总结了一下这段时间在使用 feign 的过程中的遇到的一些坑点。一、Get请求自动转化成POST的问题1、client 请求参数没有加上 RequestParam 注解问题代码:GetMapping("/showName") String showName(String name);错误提示&#xff1a…

让 APISpace 告诉你什么场景使用什么API

Q1:某商家打算搞年底促销活动,需要将活动信息通过短信的形式通知给用户,这个场景可以用什么接口? 发送通知类的短信,可以使用 通知短信 API~ 通知短信,支持三大运营商,虚拟运营商短信发送&…

第14章 并发控制与恢复

第14章 并发控制与恢复 考试范围: 14.1-14.3, 14.8-14.11 考试题型: 事务操作 考试内容: 1、锁/共享锁/排它锁的概念 2、多粒度锁 Multiple Granularity 3、两阶段封锁协议 The Two-Phase Locking Protocol 两段锁协议是指同一事务对任何…

2.前端笔记-JS-JS3种书写位置、注释、输入输出

书写位置 行内式嵌入式外部文件引入 1、行内式JS 可以将单行或少量的JS代码写在HTML标签的事件属性中&#xff08;以on开头的属性&#xff09;&#xff0c;如onclick单双引号使用&#xff1a;HTML中推荐双引号&#xff0c;JS中推荐单引号&#xff0c;如 <input type&quo…

vue实现将自己网站(h5链接)分享到微信中形成小卡片(超详细)

大家好&#xff0c;我是雄雄。 前言 我们在分享公众号信息到微信或者群中的时候&#xff0c;会出现一个小卡片&#xff0c;如下所示&#xff1a; 但是呢&#xff0c;这种小卡片只能走微信的接口来实现&#xff0c;比如我们从公众号、小程序中分享的内容可以是这样的。如果我们…

0基础转行,四个月,改变了我的人生!

转行对于很多人而言都是一个新的开始&#xff0c;但有的人是决定了立马去做&#xff0c;而有的人则是犹犹豫豫&#xff0c;我考虑考虑吧、还没有决定好、过段时间再说吧…… 就这样&#xff0c;相似情况的两个人&#xff0c;最后有了不同的结果。 很多人总是以我很忙、学历不高…

自学100天,零基础转行软件测试,我要以更好的姿态奔赴下一场山海!

三年大专一场空 专业是电子商务&#xff0c;18年毕业&#xff0c;当时在报考时时觉得电子商务挺高大上的&#xff0c;觉得电商肯定会有前途&#xff0c;以后毕业肯定好找工作&#xff0c;跟大多数人一样&#xff0c;我开始幻想我以后毕业以后的纸醉金迷的生活&#xff0c;我以…

模数转换器ADC

模数转换器ADC F28335内部的ADC模块是一个12位分辨率的、具有流水线结构的模数转换器,其结构框图如图11-1所示。从图11-1可以看到,F28335的ADC模块一共具有16个采样通道,分成了两组,一组为ADCINAO~ ADCINA7,另一组为ADCINBO~ADCINB7。A组的通道使用采样保持器A,也就是图…

【SCI论文解读复现NO.1】基于Transformer-YOLOv5的侧扫声纳图像水下海洋目标实时检测

前言 此前出了目标改进算法专栏&#xff0c;但是对于应用于什么场景&#xff0c;需要什么改进方法对应与自己的应用场景有效果&#xff0c;并且多少改进点能发什么水平的文章&#xff0c;为解决大家的困惑&#xff0c;此系列文章旨在给大家解读最新目标检测算法论文&#xff0…

【小学信息技术教资面试】《制作通讯录》教案

1.题目&#xff1a;制作通讯录 2.内容&#xff1a; 3.基本要求&#xff1a; &#xff08;1&#xff09;使用任务驱动法进行教学。 &#xff08;2&#xff09;掌握表格的插入和信息的填写。 &#xff08;3&#xff09;试讲时间是10分钟。 《制作通讯录》教案 一、教学目标&am…

我国核桃种植深加工行业供给较为充足 未来大健康消费时代将带来广阔市场

根据观研报告网发布的《2022年中国核桃种植深加工行业分析报告-行业竞争策略与发展动向研究》显示&#xff0c;核桃加工分为初加工与深加工。其中核桃深加工包括核桃油的压榨、核桃蛋白粉的制备、以核桃仁为原料生产休闲食品、以核桃青皮、壳等为原料生产加工日化产品等&#x…

Java agent 使用

一、前言 于一个即将上线的应用来说&#xff0c;系统监控是必不可少的&#xff0c;为什么需要监控呢&#xff1f;应用是跑在服务器上的&#xff0c;应用在运行过程中会发生各自意想不到的问题&#xff0c;像大家熟知的OOM&#xff0c;mysql故障&#xff0c;服务器宕机&#xff…

SpringBoot+Vue实现前后端分离的教务评教系统

文末获取源码 开发语言&#xff1a;Java 使用框架&#xff1a;spring boot 前端技术&#xff1a;JavaScript、Vue.js 、css3 开发工具&#xff1a;IDEA/MyEclipse/Eclipse、Visual Studio Code 数据库&#xff1a;MySQL 5.7/8.0 数据库管理工具&#xff1a;phpstudy/Navicat JD…

将spark的数据保存到MySQL

文章目录前言环境的准备是必要的下载解压放置文件代码书写注意事项结束语前言 我们用spark对数据进行分析和提取数据后要对得到的数据进行保存接下来的内容是将数据保存到MySQL数据库中 环境的准备是必要的 下载 &#xff08;本小博主已经为看官大人准备好了下载地址点击下载…