Linux内存管理4---虚拟地址空间管理
1.前言
本文所述关于内存管理的系列文章主要是对陈莉君老师所讲述的内存管理知识讲座的整理。
本讲座主要分三个主题展开对内存管理进行讲解:内存管理的硬件基础、虚拟地址空间的管理、物理地址空间的管理.
本文将主要以X86架构为例来介绍虚拟地址空间的管理。
2.虚拟地址空间展示

图 进程地址空间
- 程序一旦被执行就成为一个进程,内核就会为每个运行的进程提供了大小相同的虚拟地址空间,这使得多个进程可以同时运行而又不会互相干扰
- 具体来说一个进程对某个地址的访问,绝不会干扰其他进程对同一地址的访问。
- 每个进程都拥有4GB(32位)大小的虚拟地址空间,每个进程都拥有私有的前3G空间,即“用户空间”;而后1G空间被每个进程所共享,即“内核空间”。
- 进程访问内核空间的唯一途径为系统调用。
- 在每个进程眼中,它们各自拥有4GB大小的地址空间;而在CPU眼中,任意时刻,一个CPU上只存在一个虚拟地址空间。虚拟地址空间随着进程间的切换而变化。
3.虚拟内存实现机制

图 虚拟内存实现机制
- 地址映射
可执行文件从磁盘映射到虚拟地址空间
虚拟地址空间映射到物理地址空间
- 请页
将可执行文件从磁盘调入物理内存
- 内存的分配与回收
- 缓存和刷新
- 交换机制
把内存的内容换到磁盘,把磁盘内容换到内存,需要用到文件系统
4. 进程地址空间布局图

图 进程地址空间布局图
- Linux把进程的地址空间划分为多个区间,这些区间称为虚拟内存区域(VMA)
- 可以通过cat /proc/进程号/maps来查看进程的地址空间布局

图 mymmap可执行文件的内存布局
5. 进程用户空间的描述
- 一个进程的用户地址空间主要由mm_struct结构和vm_area_structs结构来描述
- mm_struct结构对进程整个用户空间进行描述
- mm_area_structs结构对用户空间中各个内存区进行描述
- mm_struct内存描述符基本字段

图 内存描述符基本字段
- vm_area_structs主要字段

图 vm_area_structs主要字段
6. 相关数据结构之间的关系

图 相关数据结构之间的关系
- 进程在内核中通过task_struct结构体进行描述
- task_struct->mm指向与该进程用户空间对应的mm_struct结构体
- mm_struct->mmap指向VMA双链表
- 使用current->mm->mmap可获得VMA链表的头指针
- current->mm->mmap->vm_next获得指向该VMA双链表的下一个结点的指针
7. 新建虚拟内存区域

图 mmap()和do_mmap()
- 在内核空间通过do_mmap()创建一个新的虚拟内存区域
- 在用户空间通过mmap()系统调用获取do_mmap()的功能
8.内存映射
- 内存映射
把文件从磁盘映射到进程用户空间的一个虚拟内存区域中,对文件的访问转化为对虚存区的访问。
当从这段虚拟内存中读数据时,就相当于读磁盘文件中的数据,将数据写入这段虚拟内存时,则相当于将数据直接写入磁盘文件。
这样就可以在不使用基本I/O操作函数read和write的情况下执行I/O操作。
有共享的、私有的虚存映射和匿名映射
- mmap()函数

图 mmap函数说明
- mmap的演示
如下实现了将磁盘文件mapping_file.txt映射到进程的虚拟用户空间,通过修改首字符,实现对文件的读写

图 mmap的演示
9.虚拟内存与物理内存
(1)用户态的程序经过编译执行形成进程,进程虽然可以任意访问整个用户空间的内存,但这毕竟属于虚拟地址空间,因此进程最终必须访问到物理内存。
(2)将虚拟内存和物理内存连接起来的就是分页机制,它在虚拟地址和物理地址之间建立了一种映射关系。
(3)进程访问的是虚拟地址,虚拟地址通过页表的转换最终形成物理地址。如果某个虚拟地址在页表中并不存在和某个物理地址之间的映射,那么系统将发生一次缺页异常。
(4)当一个进程运行时,CPU访问的地址是用户空间的虚拟地址。Linux采用请页机制来节约物理内存,也就是说它仅仅将当前要使用的用户空间中少量页装入物理内存。
(5)当访问的虚拟内存页面尚未装入物理内存时,处理器将产生一个缺页异常。当发生缺页异常时,操作系统必须从磁盘或交换文件中将要访问的页装入物理内存。
10. 参考文献

[7].GNU的C语言,http://www.faqs.org/docs/learnc/
[8].GCC参考手册
Linux内存管理4---虚拟地址空间管理的更多相关文章
- Linux进程虚拟地址空间管理2
2017-04-12 前篇文章对Linux进程地址空间的布局以及各个部分的功能做了简要介绍,本文主要对各个部分的具体使用做下简要分析,主要涉及三个方面:1.MMAP文件的映射过程 2.用户 内存的动态 ...
- linux内核分析之进程地址空间管理
1.struct task_struct 进程内核栈是操作系统为管理每一个进程而分配的一个4k或者8k内存大小的一片内存区域,里面存放了一个进程的所有信息,它能够完整的描述一个正在执行的程序:它打开的 ...
- 【转】 linux内存管理
一 为什么需要使用虚拟内存 大家都知道,进程需要使用的代码和数据都放在内存中,比放在外存中要快很多.问题是内存空间太小了,不能满足进程的需求,而且现在都是多进程,情况更加糟糕.所以提出了虚拟内存,使得 ...
- linux内存管理(repost)
一 为什么需要使用虚拟内存 大家都知道,进程需要使用的代码和数据都放在内存中,比放在外存中要快很多.问题是内存空间太小了,不能满足进程的需求,而且现在都是多进程,情况更加糟糕.所以提出了虚拟内存,使得 ...
- [国嵌攻略][106][Linux内存管理子系统]
内存管理子系统 1.虚拟地址与物理地址的映射 2.物理内存的分配 Linux虚拟地址空间分布 设备最后访问的一定是物理地址,但Linux系统中使用的都是虚拟地址.虚拟地址简单的来说就是程序中使用的地址 ...
- Linux内存管理(一)
Linux内存管理之一:基本概念篇 物理地址.线性地址(虚拟地址)和逻辑地址:阐述段式管理和页式管理基本概念:Linux操作系统内存管理和虚拟内存概念:为内核开发做一个基础铺垫. 内存是linux内核 ...
- C++ | 虚拟地址空间
在 x86 32位系统下,进程的虚拟地址空间为 232 (4G)大小,其中在windows系统下4G地址空间中0x00000000-0x7FFFFFFF 是用户地址空间,0x80000000-0xFF ...
- LInux进程虚拟地址空间的管理
2017-04-07 脱离物理内存的管理,今天咱们来聊聊进程虚拟内存的管理.因为进程直接分配和使用的都是虚拟内存,而物理内存则是有系统“按需”分配给进程,在进程看来,只知道虚拟内存的存在! 前言: 关 ...
- linux 内存地址空间管理 mm_struct
http://blog.csdn.net/yusiguyuan/article/details/39520933 Linux对于内存的管理涉及到非常多的方面,这篇文章首先从对进程虚拟地址空间的管理说起 ...
随机推荐
- 学习Spring Boot:(二十一)使用 EhCache 实现数据缓存
前言 当多次查询数据库影响到系统性能的时候,可以考虑使用缓存,来解决数据访问新能的问题. SpringBoot 已经为我们提供了自动配置多个 CacheManager 的实现,只要去实现使用它就可以了 ...
- Elasticsearch 常见问题的解决思路
本文为es性能监控基础的扩展,大家可以先看下性能监控基础,熟悉下es的基本原理.为翻译性质文档,感谢原作者,原始文档地址 类似于汽车的运行方式,Elasticsearch旨在让用户快速上手和运行,而无 ...
- Arch Linux中禁用UTC解决双系统时间问题
原因 Windows双系统时间不统一在于时间表示有两个标准:localtime 和 UTC(Coordinated Universal Time) .UTC 是与时区无关的全球时间标准.尽管概念上有差 ...
- Linux中配置Aria2 RPC Server
启动Aria2 RPC Server 直接在终端中执行aria2c --enable-rpc --rpc-allow-origin-all可直接开启RPC服务. 这种方法并不能进行个性化的参数设置,需 ...
- C# String类&Math类&DateTime类
String类: String a = "abcdefghijklmnopqrstuvwxyz"; int length = a.length; //获取字符串的长度: a = ...
- spring MVC 如何接收前台传入的JSON对象数组
spring MVC 如何接收前台传入的JSON对象数组 主要方法: (主要用到的包是 net.sf.json 即:json-lib-2.3-jdk15.jar 完整相关jar包: commons- ...
- Docker跨主机网络解决方案
前言:前面的部分一直都是单机跑docker,但实际生产环境不可能只用一台来跑.肯定会用到多台,因为他们都是内部私有ip,那么多台主机之间的容器如何通信?这个是个很头疼的问题!目前主流几种方法如下:1. ...
- pyglet--旋转的矩形
展示怎么制作动画.... #-*- coding:utf-8 -*- from pyglet.gl import * from pyglet import clock def draw_rect(x, ...
- java连接mysql的过程
今天突然心血来潮,想要用java连接mysql,记得以前是在vs2010的环境下用C#连接sql sever,其实他们的方法都差不多. 现在就可以简单的介绍下java如何连接mysql 第一步,设计m ...
- liunx必知必会(1)
一.liunx目录结构: (1)/bin中 - 用户二进制文件 包含二进制可执行文件. 在单用户模式下,你需要使用的常见Linux命令都位于此目录下.系统的所有用户使用的命令都设在这里. (2)/sb ...