Linux内存映射实现

1、内存管理架构图

分为用户空间,内核空间,硬件三个层面:
在这里插入图片描述

方便用户——段——虚拟内存
方便操作系统——页——物理内存

1、用户空间
应用程序malloc()申请内存,free()释放内存(是内存分配器ptmalloc提供的接口),内存分配器ptmalloc使用系统调用brk()或者mmap()向内核以页为单位申请内存,然后划分成小内存块分配给程序
2、内核空间
虚拟内存管理,负责把用户地址映射成虚拟地址,从进程的虚拟地址空间分配虚拟页

  • sys_brk()用来扩大缩小堆,
  • sys_mmap()用来内存映射区域分配虚拟页
  • sys_munmap()用来释放虚拟页
    页分配器负责分配物理页。

3、硬件
内存管理单元MMU,负责把虚拟地址转换成物理地址。
内存管理单元包含页表缓存TLB,保存最近使用过的页表映射
解决CPU以及内存处理速度不匹配问题,加了缓存

2、虚拟地址空间

虚拟地址空间的内部又被分为内核空间和用户空间

32 位系统的内核空间占用 1G,位于最高处,剩下的 3G 是用户空间。大小用TASK_SIZE表示,即0X100000000

在这里插入图片描述

64位系统虚拟地址最大为48位,所以中间会有空缺。属于不规范地址,不允许使用
在这里插入图片描述

2.1 用户虚拟地址空间

包括:

(1) 代码段,包括代码和常量等。

(2) 数据段,包括全局变量等。

(3) 未初始化数据段,例如int赋值0等。

(4) ,包括动态分配的内存。

(5) 内存映射区域,把文件区间映射到虚拟地址空间。

(6) ,包括局部变量和函数调用。底部存放环境变量和参数字符串。

在这里插入图片描述
上图为传统布局:内存映射区域自底向上增长,起始地址是TASK_UNMAPPED_BASE+随机值
内核支持为内存映射区域、栈和堆选择随机的起始地址

可见,内存变化最大的区域从大到小排序是(1)堆(2)内存映射区域(3)栈

2.2内核地址空间布局

在这里插入图片描述

3、物理地址空间

虚拟地址到物理地址映射,由硬件自动完成,不过多赘述

4、内存映射

内存映射指在进程的虚拟地址空间创建一个映射,有两种
1、文件映射:就是磁盘中的数据通过文件系统映射到内存再通过文件映射映射到虚拟空间.这样,用户就可以在用户空间通过 open ,read, write 等函数区操作文件内容.
2、匿名映射: 就是用户空间需要分配一定的物理内存来存储数据,这部分内存不属于任何文件,内核就使用匿名映射将内存中的 某段物理地址与用户空间一一映射,这样用户就可用直接操作虚拟地址来范围这段物理内存.

至于实际的代码,文件映射的操作就是: open,read,write,close,mmap… 操作的虚拟地址都属于文件映射.
malloc 分配的虚拟地址属于匿名映射.

普通文件:

将可执行文件加载到内存中,进行的映射是普通文件的映射。比如data段text段等,是私有的文件映射

匿名文件

  • 2
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值