【Linux内核】虚拟地址空间布局架构

虚拟地址空间布局架构(Linux内核学习)

1.Linux内核整体架构及子系统

image-20210908184625839

内核对下管理硬件,对上通过运行时库对应用提供服务

image-20210908200143443

  1. 用户空间

    使用malloc()分配内存通过free()释放内存

  2. 内核空间

    虚拟进程负责从进程的虚拟地址空间分配虚拟页,sys_brk来扩大或收缩堆,sys_mmap负责在内存映射区分配虚拟页,

    页分配器负责分配物理页

    不连续内存分配器提供分配内存的接口vmalloc和释放内存接口vfree,申请连续的物理页的成功率比较低,可以申请不连续的物理页,r然后映射到连续的虚拟页,及虚拟地址连续而物理地址不连续

    内存控制组来控制进程占用的资源,当内存碎片化的时候,找不到连续的物理页,内存碎片整理通过迁移方式得到连续的物理页,当内存不足的时候,负责回收物理页

  3. 硬件

    MMU1包含一个页表缓存,保存最近使用过的页表映射,避免每次都要查询虚拟页对应的物理页,解决了CPU执行速度与内存速度不匹配的问题

image-20210908203424221

来个例子:

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
constexpr int MAX = 1024;int main(int argc, char const *argv[])
{/*sbrk函数在内核的管理下将虚拟地址空间映射到内存,供malloc函数使用。*/void *p = sbrk(0);void *old = p;p = (int *)sbrk(MAX * MAX);if (p == (void *)(-1)){std::cout << "sbrk error\n";exit(0);}printf("old:%p\tp=%p\n", p, old);void *new_ = sbrk(0);printf("new:%p", new_);sbrk(-MAX * MAX);return 0;
}

输出

old:0x55555557a000      p=0x55555557a000
new:0x55555567a000

可见成功分配了新的内存.

那我们如何更加具体的看到是否获取了内存呢?

更改代码如下:

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
constexpr int MAX = 1024;int main(int argc, char const *argv[])
{/*sbrk函数在内核的管理下将虚拟地址空间映射到内存,供malloc函数使用。*/void *p = sbrk(0);void *old = p;p = (int *)sbrk(MAX * MAX);if (p == (void *)(-1)){std::cout << "sbrk error\n";exit(0);}printf("old:%p\tp=%p\n", p, old);void *new_ = sbrk(0);printf("new:%p\n", new_);printf("pid= %d\n", getpid());while (true){}sbrk(-MAX * MAX);return 0;
}

运行,不要停止

输出为:

old:0x55555557a000      p=0x55555557a000
new:0x55555567a000
pid= 1193

打开新终端输入cat /proc/1193/maps(一切皆文件)查看内存情况:

image-20210908211016646

后续就不在演示了(懒)

2.虚拟内存空间内存架构

image-20210908211415941

linux-4.4.4\arch\arm64\include\asm\memory.h

#define TASK_SIZE_64		(UL(1) << VA_BITS)//64位操作系统  //VA_BITS 编译内核的时候选择的虚拟地址的位数#ifdef CONFIG_COMPAT
#define TASK_SIZE_32		UL(0x100000000)    //32位操作系统

进程的用户虚拟地址空间包含区域:代码段、数据段、未初始化数据段;
动态库的代码段、数据段和未初始化数据段;存放动态生成的数据的堆;
存放局部变量和实现函数调用的栈;
把文件区间映射到虚拟地址空间的内存映射区域;存放在栈底部的环境变量和参数字符串。

部分内核代码:

struct mm_struct {struct vm_area_struct *mmap;//虚拟内存区域链表		/* list of VMAs */struct rb_root mm_rb;//虚拟内存区红黑树u32 vmacache_seqnum;                   /* per-thread vmacache */
#ifdef CONFIG_MMU    //在内存映射区找到一个没有映射的区域unsigned long (*get_unmapped_area) (struct file *filp,unsigned long addr, unsigned long len,unsigned long pgoff, unsigned long flags);unsigned long mmap_base;	//内存映射区起始地址	/* base of mmap area */unsigned long mmap_legacy_base;         /* base of mmap area in bottom-up allocations */unsigned long task_size;	//用户虚拟空间长度	/* size of task vm space */unsigned long highest_vm_end;		/* highest vma end address */pgd_t * pgd;atomic_t mm_users;	//共享一个用户虚拟空间的进程数量,进程包含的线程的数量		/* How many users with user space? */atomic_t mm_count;			/* How many references to "struct mm_struct" (users count as 1) */atomic_long_t nr_ptes;	unsigned long hiwater_rss;//进程所拥有的最大页框数	/* High-watermark of RSS usage */unsigned long hiwater_vm;	// 最大页数/* High-water virtual memory usage */unsigned long total_vm;	//进程页数	/* Total pages mapped */unsigned long locked_vm;//锁住不能交换的页数	/* Pages that have PG_mlocked set */unsigned long pinned_vm;	/* Refcount permanently increased */unsigned long shared_vm;	/* Shared pages (files) */unsigned long exec_vm;		/* VM_EXEC & ~VM_WRITE */unsigned long stack_vm;		/* VM_GROWSUP/DOWN */unsigned long def_flags;unsigned long start_code, end_code, start_data, end_data;//代码段起始结束,数据段起始结束unsigned long start_brk, brk, start_stack;//堆 栈的起始地址

image-20210908215430545

image-20210908220500685

image-20210908220535224

image-20210908220623757

image-20210908220734028

**我所有的学习笔记都在Github仓库里:https://github.com/fanxing-6/CPP-learning-notes **

,如果访问Github有问题也可以访问Gitee:CPP-learning-notes: C++学习笔记 (gitee.com)

本人能力有限,笔记难免有疏漏,如果有错误,欢迎各位关注公众号与我交流,一定会及时回复

请添加图片描述

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

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

相关文章

【Linux内核】内存映射原理

【Linux内核】内存映射原理 物理地址空间 物理地址是处理器在总线上能看到的地址,使用RISC(Reduced Instruction Set Computing精简指令集)的处理器通常只实现一个物理地址空间,外围设备和物理内存使用统一的物理空间, 有些架构的处理器把分配给外围设备的物理地址称为设备内存…

javascript学习系列(1):数组中的map方法

最好的种树是十年前,其次是现在。歌谣 每天一个前端小知识 提醒你改好好学习了 知乎博主 csdn博主 b站博主 放弃很容易但是坚持一定很酷 我是歌谣 喜欢就一键三连咯 你得点赞是对歌谣最大的鼓励 1前言 在我们的日常开发中 不免会有很多需要处理数据的方法 本节主要说一说m…

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

【Linux内核】物理内存组织结构 系统调用mmap 物理内存组织结构 体系结构 目前多处理器系统有两种体系结构&#xff1a; 1&#xff09;非一致内存访问&#xff08;Non-Unit Memory Access&#xff0c;NUMA&#xff09;&#xff1a;指内存被划分成多个 内存节点的多处理器系…

脱离 Rails 看 Ruby

在开始这篇文章之前&#xff0c;我需要澄清一些事情。首先&#xff0c;这不是一篇关于 Ruby on Rails 的文章。如果您希望了解 Rails&#xff0c;每周&#xff08;甚至每小时&#xff09;都有相关的文章和 blog 出现&#xff0c;它们都对这个令人兴奋的框架的众多特性大加推崇&…

如何方便的让你的集合引发改变事件

在我们开发自定义控件的过程中,我们常常会给控件添加集合属性。比如定制Grid控件就会有Column集合。当集合属性发生变化时&#xff0c;比如添加新元素&#xff0c;删除新元素&#xff0c;我们要通知控件去重绘以反映新的变化。我们可以创建一个集合类&#xff0c;在类里添加一个…

[汇编语言]-第八章 div指令,伪指令dd,dup

1- div除法指令 (1) 除数: 有8位和16位两种,在一个寄存器或内存单元中. (2) 被除数: 默认放在AX和DX或AX中 除数为8位, 被除数为16位, 默认在AX中存放. 除数为16位, 被除数为32位, 在DX或AX中存放. AX存放低16位,DX存放高16位. (3) 结果 除数为8位, 则AL存储除法操作的商, AH存…

lambda表达式浅析【C++学习笔记】

lambda表达式浅析【C学习笔记】 基本用法: auto f [/*捕获列表*/](/*参数*/)->int /*后置返回值类型*/{/** 函数体*/};捕获列表: [] : 不捕获任何变量 [变量名] : 表示值捕获,不可修改 [] :按值捕获所有变量,不可修改 [&] : 按引用捕获可以修改 [this] : 在类中捕…

【Cocos2d-x for WP8 学习整理】(2)Cocos2d-Html5 游戏 《Fruit Attack》 WP8移植版 开源...

【Cocos2d-x for WP8 学习整理】&#xff08;2&#xff09;Cocos2d-Html5 游戏 《Fruit Attack》 WP8移植版 开源 原文:【Cocos2d-x for WP8 学习整理】&#xff08;2&#xff09;Cocos2d-Html5 游戏 《Fruit Attack》 WP8移植版 开源这一阵花了些时间&#xff0c;把 cocos2d-h…

碰撞,处理碰撞,发射 Learn Unreal Engine (with C++)

本文使用打砖块游戏举例 碰撞,处理碰撞 碰撞就相当于一个Actor进入另一个Box中,用这个思路就可以处理碰撞了 OnComponentBeginOverlap 当某些内容开始重叠此组件时调用的事件&#xff0c;例如玩家进入触发器。 **委托 事件 **1 AddDynamic( UserObject, FuncName ) 用于…

传送,条件加速 Learn Unreal Engine (with C++)

本文以吃豆人游戏为例UE4项目: 自制UE4 小游戏 (gitee.com) 传送 pawn进入box触发OnActorBeginOverlap获取目标位置,下一帧将pawn坐标更改为目标位置 首先需要重叠函数与开始重叠事件绑定 OnActorBeginOverlap.AddDynamic(this, &ATeleporterActor::OnOverlapBegin);头文件…

获取摄像机,摄像机切换Learn Unreal Engine (with C++)

摄像机应该是使用最普遍的组件了 获取摄像机,摄像机切换 新建C类(以CameraActor为父类) 将摄像机在地图中放置 头文件声明 virtual void BeginPlay() override;UPROPERTY(EditAnywhere, BlueprintReadWrite)UBoxComponent* OverlapVolume; // 盒体组件,用于检测人物碰撞UPR…

android报错及解决1--Bitmap加载时,报bitmap size exceeds VM budget

报错描述&#xff1a; 用Bitmap加载图片资源时&#xff0c;报错java.lang.OutOfMemoryError: bitmap size exceeds VM budget 原因分析&#xff1a; android系统限制&#xff0c;只给图片分配8M内存&#xff0c;超过就蹦。图片虽然几十K&#xff0c;可能是压缩格式&#xff0c;…

主角的创建与选择 Learn Unreal Engine (with C++)

主角创建有两种方式,本教程以SpaceshipBattle fanxingin/UE4项目 - 码云 - 开源中国 (gitee.com) 1. 新建游戏模式方式 新建一个蓝图类,选择游戏模式基础 在蓝图类的细节中将默认pawn类选择主角的蓝图类 在项目设置->地图和模式->默认模式->默认游戏模式 默认游…

控制`Actor`朝向,运动 Learn Unreal Engine (with C++)

控制Actor的朝向,以及Actor的运动 SpaceshipBattle fanxingin/UE4项目 - 码云 - 开源中国 (gitee.com) 控制Actor朝向鼠标 设置鼠标在游戏中可见 获取玩家控制器鼠标可见设置为true PC Cast<APlayerController>(GetController()); PC->bShowMouseCursor true;获取…

.Net开发人员应该下载的十种必备工具(三)

NDoc 编写代码文档资料几乎总是一项令人畏惧的任务。我所说的不是早期设计文档&#xff0c;甚至也不是更为详细的设计文档&#xff1b;我说的是记录类上的各个方法和属性。NDoc 工具能够使用反射来分析程序集&#xff0c;并使用从 C# XML 注释生成的 XML 自动为代码生成文档资料…

Actor范围内随机生成 Learn Unreal Engine (with C++)

Actor范围内随机生成 Learn Unreal Engine (with C) SpaceshipBattle fanxingin/UE4项目 - 码云 - 开源中国 (gitee.com) Actor范围内随机生成 新建box组件 SpawnArea CreateDefaultSubobject<UBoxComponent>(TEXT("SpawnArea"));RootComponent SpawnArea…