Linux内核有什么之内存管理子系统有什么第七回 —— 小内存分配(5)

接前一篇文章:Linux内核有什么之内存管理子系统有什么第六回 —— 小内存分配(4)

本文内容参考:

linux进程虚拟地址空间

《趣谈Linux操作系统 核心原理篇:第四部分 内存管理—— 刘超》

4.6 深入理解 Linux 虚拟内存管理

特此致谢!

二、小内存分配 —— brk与sbrk

上一回在讲sys_brk函数代码的时候,讲到了struct vm_area_struct,打根上详细介绍了其相关的概念。每个vm_area_struct结构对应于虚拟内存空间中的唯一虚拟内存区域 VMA。虚拟内存区域就是上边的代码段(Text区域)、数据段(Data区域)、BSS段(BSS区域)、堆、栈等,它们每一个都对应一个唯一的vm_area_struct结构(实例)。如下图所示:

本回对于此结构体成员进行详细解析。为了便于理解,再次贴出struct vm_area_struct的定义,在include/linux/mm_types.h中,代码如下:

/*
 * This struct describes a virtual memory area. There is one of these
 * per VM-area/task. A VM area is any part of the process virtual memory
 * space that has a special rule for the page-fault handlers (ie a shared
 * library, the executable area etc).
 */
struct vm_area_struct {
	/* The first cache line has the info for VMA tree walking. */
 
	unsigned long vm_start;		/* Our start address within vm_mm. */
	unsigned long vm_end;		/* The first byte after our end address
					   within vm_mm. */
 
	struct mm_struct *vm_mm;	/* The address space we belong to. */
 
	/*
	 * Access permissions of this VMA.
	 * See vmf_insert_mixed_prot() for discussion.
	 */
	pgprot_t vm_page_prot;
	unsigned long vm_flags;		/* Flags, see mm.h. */
 
	/*
	 * For areas with an address space and backing store,
	 * linkage into the address_space->i_mmap interval tree.
	 *
	 * For private anonymous mappings, a pointer to a null terminated string
	 * containing the name given to the vma, or NULL if unnamed.
	 */
 
	union {
		struct {
			struct rb_node rb;
			unsigned long rb_subtree_last;
		} shared;
		/*
		 * Serialized by mmap_sem. Never use directly because it is
		 * valid only when vm_file is NULL. Use anon_vma_name instead.
		 */
		struct anon_vma_name *anon_name;
	};
 
	/*
	 * A file's MAP_PRIVATE vma can be in both i_mmap tree and anon_vma
	 * list, after a COW of one of the file pages.	A MAP_SHARED vma
	 * can only be in the i_mmap tree.  An anonymous MAP_PRIVATE, stack
	 * or brk vma (with NULL file) can only be in an anon_vma list.
	 */
	struct list_head anon_vma_chain; /* Serialized by mmap_lock &
					  * page_table_lock */
	struct anon_vma *anon_vma;	/* Serialized by page_table_lock */
 
	/* Function pointers to deal with this struct. */
	const struct vm_operations_struct *vm_ops;
 
	/* Information about our backing store: */
	unsigned long vm_pgoff;		/* Offset (within vm_file) in PAGE_SIZE
					   units */
	struct file * vm_file;		/* File we map to (can be NULL). */
	void * vm_private_data;		/* was vm_pte (shared mem) */
 
#ifdef CONFIG_SWAP
	atomic_long_t swap_readahead_info;
#endif
#ifndef CONFIG_MMU
	struct vm_region *vm_region;	/* NOMMU mapping region */
#endif
#ifdef CONFIG_NUMA
	struct mempolicy *vm_policy;	/* NUMA policy for the VMA */
#endif
	struct vm_userfaultfd_ctx vm_userfaultfd_ctx;
} __randomize_layout;

各个成员的具体含义如下: 

  • unsigned long vm_start

vm_mm内的起始地址。

  • unsigned long vm_end

vm_mm结束地址后的第一个字节。

vm_start 指向了这块虚拟内存区域的起始地址(最低地址),vm_start 本身包含在这块虚拟内存区域内。vm_end 指向了这块虚拟内存区域的结束地址(最高地址),而 vm_end 本身包含在这块虚拟内存区域之外,所以 vm_area_struct 结构描述的是[vm_start, vm_end)这样一段左闭右开的虚拟内存区域。

  • struct mm_struct *vm_mm

所属的地址空间。由于每个进程的虚拟地址空间都是独立、互不干扰的,因此每个进程都有唯一的 mm_struct结构体,其是专门描述进程虚拟地址空间的内存描述符。在这里代表具体的虚拟内存区域(VMA)就是上边的代码段(Text区域)、数据段(Data区域)、BSS段(BSS区域)、堆、栈等所属的虚拟地址空间(vm_mm)。

  • pgprot_t vm_page_prot和unsigned long vm_flags

此VMA(虚拟内存区域)的访问权限。更详细地讲解,vm_page_prot和vm_flags都是用来标记vm_area_struct结构表示的这块虚拟内存区域的访问权限和行为规范的。由于虚拟内存最终要和物理内存一一映射起来,所以在虚拟内存空间中也有虚拟页的概念与之对应,虚拟内存中的虚拟页映射到物理内存中的物理页。无论是在虚拟内存空间中还是在物理内存中,内核管理内存的最小单位都是页。

vm_page_prot偏向于定义底层内存管理架构中页这一级别的访问控制权限,它可以直接应用在底层页表中,它是一个具体的概念。 虚拟内存区域VMA由许多的虚拟页(page)组成,每个虚拟页需要经过页表的转换才能找到对应的物理页面。页表中关于内存页的访问权限就是由 vm_page_prot决定的。

vm_flags则偏向于定于整个虚拟内存区域的访问权限以及行为规范。描述的是虚拟内存区域中的整体信息,而不是虚拟内存区域中具体的某个独立页面。vm_flags是一个抽象的概念。可以通过 vma->vm_page_prot = vm_get_page_prot(vma->vm_flags) 实现到具体页面访问权限 vm_page_prot的转换。

常用的vm_flags值及对应访问权限如下表所示:

vm_flags访问权限
VM_READ可读
VM_WRITE可写
VM_EXEC可执行
VM_SHARD可多进程之间共享
VM_IO可映射至设备 IO 空间
VM_RESERVED内存区域不可被换出
VM_SEQ_READ内存区域可能被顺序访问
VM_RAND_READ内存区域可能被随机访问

  • VM_READ、VM_WRITE、VM_EXEC

定义了虚拟内存区域是否可以被读取,写入,执行等权限。

前文曾提到,代码段(Code  Segment / Text Segment)内存区域的权限是可读、可执行,但是不可写;数据段Data Segment具有可读、可写的权限但是不可执行;堆(Heap)则具有可读、可写、可执行的权限;栈(Stack)通常具有可读、可写的权限,一般很少有可执行权限;而文件映射与匿名映射区存放了共享链接库,所以也需要可执行的权限。

按照上边的说明,各个区域的权限如下图所示:

  • VM_SHARD

用于指定这块虚拟内存区域映射的物理内存是否可以在多进程之间共享,以便完成进程间通讯。设置这个值即为mmap的共享映射,不设置的话则为私有映射。

  • VM_IO

VM_IO标志的设置表示这块虚拟内存区域可以映射至设备IO空间中。通常在设备驱动程序执行 mmap进行IO空间映射时VM_IO标志才会被设置。

  • VM_RESERVED

VM_RESERVED标志的设置表示这块虚拟内存区域非常重要,在内存紧张的时候,不能被换出到磁盘中。

  • VM_SEQ_READ和VM_RAND_READ

VM_SEQ_READ的设置用来暗示内核,应用程序会对这块虚拟内存区域进行顺序读取,内核会根据实际情况决定预读后续的内存页数,以便加快下次顺序访问速度。

VM_RAND_READ的设置会暗示内核,应用程序会对这块虚拟内存区域进行随机读取,内核则会根据实际情况减少预读的内存页数甚至停止预读。

综上所述,vm_flags 就是定义整个虚拟内存区域的访问权限以及行为规范,而内存区域中内存的最小单位为页(4K),虚拟内存区域中包含了很多这样的虚拟页,对于虚拟内存区域VMA设置的访问权限也会全部复制到区域中包含的内存页中。

对于vm_area_struct结构其余成员的详细解析,请看下回。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

手把手带你创建一个自己的GPTs

大家好,我是五竹。 最近GPT又进行了大升级,这一下又甩了国内AI几条街,具体更新了哪些内容之前的一篇文章中其实已经说过了:ChatGPT 王炸升级!更强版 GPT-4 上线! 其中最重要的一点就是支持自定义GPT&…

【博士每天一篇文献-算法】A pseudo-inverse decomposition-based self-organizing modular echo

阅读时间:2023-11-6 1 介绍 年份:2022 作者:王雷,北京信息科技大学自动化学院 期刊: Applied Soft Computing 引用量:12 提出了一种基于伪逆分解的自组织模块化回声状态(PDSM-ESN&#xff09…

代码随想录算法训练营第四十九天丨 动态规划part12

309.最佳买卖股票时机含冷冻期 思路 相对于动态规划:122.买卖股票的最佳时机II (opens new window),本题加上了一个冷冻期 在动态规划:122.买卖股票的最佳时机II (opens new window)中有两个状态,持有股票后的最多现金&#xf…

一文搞懂设计模式之单例模式

大家好,我是晴天,本周我们一起来学习单例模式。本文将介绍单例模式的基本属性,两种构造单例的方法(饿汉模式和懒汉模式)以及golang自带的sync.Once()方法。 什么是单例模式 GoF对单例模式的定义是:保证一个…

【Linux】WSL安装Kali及基本操作

😏★,:.☆( ̄▽ ̄)/$:.★ 😏 这篇文章主要介绍WSL安装Kali及基本操作。 学其所用,用其所学。——梁启超 欢迎来到我的博客,一起学习,共同进步。 喜欢的朋友可以关注一下,下次更新不迷路…

<C++> stack queue模拟实现

目录 前言 一、stack的使用 1. 接口说明 2. 例题 二、模拟实现stack 三、queue的使用 四、模拟实现queue 五、deque 总结 前言 LIFO stack 1. 栈是一种容器适配器,专门设计用于在后进先出上下文(后进先出)中运行,其中元素仅从容器…

Linux之基本指令操作

1、whoami whoami:查看当前账号是谁 2、who who:查看当前我的系统当中有哪些用户,当前有哪些人登录了我的机器 3、 pwd pwd:查看我当前所处的目录,就好比Windows下的路径 4、ls ls:查看当前目录下的文件信…

算法导论6:摊还分析,显式与隐式

P258 摊还分析概念 聚合分析,利用它,我们证明对于n,一个n个操作的序列最坏情况下的花费的总时间为T(n),因此,在最坏情况下,每个操作的平均代价(摊还代价)为T(n)/n 举了例子来形容这…

头歌答案Python——JSON基础

目录 ​编辑 Python——JSON基础 第1关:JSON篇:JSON基础知识 任务描述 第2关:JSON篇:使用json库 任务描述 Python——XPath基础 第1关:XPath 路径表达式 任务描述 第2关:XPath 轴定位 任务描述…

SOME/IP 协议介绍(四)RPC协议规范

RPC协议规范 本章描述了SOME/IP的RPC协议。 传输协议绑定 为了传输不同传输协议的SOME/IP消息,可以使用多种传输协议。SOME/IP目前支持UDP和TCP。它们的绑定在以下章节中进行了解释,而第[SIP_RPC_450页,第36页]节讨论了选择哪种传输协议。…

[C国演义] 第十八章

第十八章 最长斐波那契子序列的长度最长等差数列等差序列划分II - 子序列 最长斐波那契子序列的长度 力扣链接 子序列 ⇒ dp[i] — — 以 arr[i] 结尾的所有子序列中, 斐波那契子序列的最长长度子序列 ⇒ 状态转移方程 — — 根据最后一个位置的组成来划分 初始化 — — 根…

海外媒体发稿:彭博社发稿宣传中,5种精准营销方式

在如今的信息发生爆炸时期,营销方式多种多样,但是充分体现精准营销并针对不同用户群体的需求并非易事。下面我们就根据彭博社发稿营销推广为例子,给大家介绍怎样根据不同用户人群方案策划5种精准营销方式。 1.界定总体目标用户人群在制订精准…

Flink SQL 表值聚合函数(Table Aggregate Function)详解

使用场景: 表值聚合函数即 UDTAF,这个函数⽬前只能在 Table API 中使⽤,不能在 SQL API 中使⽤。 函数功能: 在 SQL 表达式中,如果想对数据先分组再进⾏聚合取值: select max(xxx) from source_table gr…

华为ensp搭建小型园区网络规划

文章目录 前言一、拓扑图二、数据规划三、设备配置四.配置命令1.配置接入层交换机ACC11.1 设备命名,创建VLAN1.2 配置eth-trunk 11.3 配置用户端 2.配置核心层交换机CORE2.1设备命名2.2配置Eth-Trunk2.3 vlan配置ip2.4 上行接口配置 3.DHCP配置3.1 CORE: 4.配置路由…

计算机毕业设计:疲劳驾驶检测识别系统 python深度学习 YOLOv5 (包含文档+源码+部署教程)

[毕业设计]2023-2024年最新最全计算机专业毕设选题推荐汇总 1、项目介绍 基于YOLOv5的疲劳驾驶检测系统使用深度学习技术检测常见驾驶图片、视频和实时视频中的疲劳行为,识别其闭眼、打哈欠等结果并记录和保存,以防止交通事故发生。本文详细介绍疲劳驾…

ROC 曲线详解

前言 ROC 曲线是一种坐标图式的分析工具,是由二战中的电子和雷达工程师发明的,发明之初是用来侦测敌军飞机、船舰,后来被应用于医学、生物学、犯罪心理学。 如今,ROC 曲线已经被广泛应用于机器学习领域的模型评估,说…

模板初阶 C++

目录 泛型编程 函数模板 概念 格式 原理 函数模板的实例化 类模板 格式 类模板的实例化 泛型编程 当我们要实现一个交换函数,我们可以利用函数重载实现,但是有几个不好的地方 1.函数重载仅仅是类型不同,代码复用率较低,只…

pyorch Hub 系列#4:PGAN — GAN 模型

一、主题描述 2014 年生成对抗网络的诞生及其对任意数据分布进行有效建模的能力席卷了计算机视觉界。两人范例的简单性和推理时令人惊讶的快速样本生成是使 GAN 成为现实世界中实际应用的理想选择的两个主要因素。 然而,在它们出现后的很长一段时间内,GA…

知识蒸馏概述及开源项目推荐

文章目录 1.介绍2.知识2.1 基于响应的知识(response-based)2.2 基于特征的知识(feature-based)2.3 基于关系的知识(relation-based) 3.蒸馏机制3.1 离线蒸馏3.2 在线蒸馏3.3 自蒸馏 4.教师-学生架构5.蒸馏算法5.1 对抗性蒸馏(Adversarial Dis…

Linux基础开发工具之调试器gdb

文章目录 1.编译成的可调试的debug版本1.1gcc test.c -o testdebug -g1.2readelf -S testdebug | grep -i debug 2.调试指令2.0quit退出2.1list/l/l 数字: 显示代码2.2run/r运行2.3断点相关1. break num/b num: 设置2. info b: 查看3. d index: 删除4. n: F10逐过程5. p 变量名…