Linux内存管理之用户空间
32 位的平台上,线性地址空间为固定的 4GB,并且由于采用了保护机制,Linux内核将这 4GB 分为两部分,线性地址较高的 1GB(0xC0000000 到 0xFFFFFFFF )为共享的内核空间;而较低的 3GB 为每个进程的用户空间。由于每个进程都不能直接访问内核空间,而是通过系统调用间接进入内核,因此所有的进程都共享内核空间。而每个进程都拥有各自的用户空间,各个进程之间不能互相访问彼此的用户空间。
一个进程的用户地址空间主要由两个数据结构来描述。一个是 mm_struct 结构,它对进程的整个用户空间进行描述,简称内存描述符;另一个是 vm_area_struct 结构,它对用户空间中各个区间( 代码区、数据区等 )进行描述。
内存描述符
每个进程只有一个 mm_struct 结构,在每个进程的 task_struct 结构中,有一个指向该结构的指针。
一个进程的虚拟空间中可能有多个虚拟区间,对这些虚拟区间的组织形式有两种:①mmap 单链表,利于高效的遍历所有元素;②mm_rb 红黑树 适合搜索指定元素,快速定位;
mmap_cache 指向虚拟区间, 根据局部性原理,最近一次用到的虚拟区间很可能下一次还要用到,因此把最近用到的虚拟区间放到高速缓存;
pgd 指向该进程的页目录,当调度程序调度一个程序运行时就将这个地址转换成物理地址并写入CR3;
page_table_lock 和 mmap_sem 提供互斥操作;
还有代码段、数据段等起始地址和结束地址。
虚拟内存区域( VMA )
虚拟内存区域由 vm_area_struct 结构体描述,每一块虚拟内存区都是由连续的虚拟地址组成。每个 vm_area_struct 代表了不同的内存区域。
划分出区间的原因是:
每个虚存区可能来源不同,有的可能来自于可执行文件,有的可能来自共享库,有的可能是动态分配的内存区,对不同的虚存区可能有不同的访问权限,也可能有不同的操作。因此Linux将进程的用户空间分割管理,并利用虚存区处理函数( vm_ops )来抽象对不同来源虚存区的处理方法。面向对象的思想,相当于class了一个对象表示虚存区,有属性,有操作。
vm_ops 结构中包含的是函数指针,nopage()是当虚存页面不在物理内存而引起的缺页异常时所应该调用的函数。
相关数据结构之间的关系
进程用户空间的创建
在调用 fork() 系统调用创建一个新进程时就为这个进程创建了一个完整的用户空间。
简单的说在创建的过程中所做的工作是 mm_struct 结构的建立、vm_area_struct 结构的建立以及页目录和页表的建立。并没有真正地复制一个物理页面,这也是为什么 Linux 内核能迅速创建进程的原因之一。
虚存映射
Linux并不将可执行映像装入到物理内存,相反,可执行文件只是被装载到进程的用户空间中。当调用 exec() 系统调用开始执行一个进程时,进程的可执行映像被装入到进程的用户地址空间,如果还用到任何一个共享库,那么共享库页必须装入到进程的用户空间。随着进程的运行,被引用的程序部分会由操作系统装入到物理内存,这种将映像映射到进程用户空间的方法被称为“虚存映射”,也就是把文件从磁盘映射到进程的用户空间,这样把对文件的访问转化为对虚存区的访问。
有两种类型的虚存映射:①
共享的:有几个进程共享这一映射,如果一个进程对共享的虚存区进行写,其他进程都能感觉到,而且会修改磁盘上对应的文件。②
私有的:进程创建的这种映射只是为了读文件,对虚存区的写操作不会修改磁盘上的文件。
如果映射与文件无关,就叫匿名映射,比如堆和栈。
当可执行映像映射到进程的用户空间时,将产生一组 vm_area_struct 结构来描述各个虚拟区间的起始点和终止点,每个 vm_area_struct 结构代表可执行映像的一部分。
一个进程基本上可以分为如下几种 VMA 区域:
代码 VMA,权限只读、可执行;有映像文件
数据 VMA,权限可读写、可执行;有映像文件
堆 VMA,权限可读写、可执行;无映像文件,匿名,可向上扩展
栈 VMA,权限可读写、不可执行;无映像文件,匿名,可向下扩展
这一部分可结合可执行文件的装载和动态链接的相关内容来学习。一个常见进程的虚拟地址空间基本是下面这样的:
本文转自:小组15级成员--tanswer
原文地址:
http://blog.csdn.net/tanswer_/article/details/78764778
(更多详细内容,点击左下角【阅读原文】)
- 如何在Windows 10安装和使用Linux的Bash shell
- 怎么样可以吧爱奇艺或者优酷上的视频下载到手机内存卡里
- 只读存储器,内存,外存和硬盘的区别
- 谁来分析下全面质量管理相比六西格玛培训的局限性?
- 北京中传和一酒店管理有限公司是骗子,刷单骗子?
- sublime text 2 的包管理为什么始终安装不上
- hadoop2.x的mapreduce怎么解决内存受限的
- OPPOr9无法删除音乐从文件管理中
- Iphone7 32G实际内存有多少呢。够用吗
- 如何在虚拟机中安装linux,在linux中安装oracle