进程的虚拟内存布局
来源:互联网 发布:intent 传递数据 编辑:程序博客网 时间:2024/06/02 15:44
每一个用户态进程拥有独立的3GB用户态虚拟地址空间,共享1GB的内核空间,而这3GB的地址不可能都映射了物理内存。task_struct的mm成员就是用来描述这3GB的虚拟地址信息的。对于内核态进程,由于没有3GB的用户态虚拟地址空间,所以其mm结构为NULL,可是为什么要在task_struct中设置mm和active_mm两个mm_struct成员呢?这是由于内核线程没有用户态地址空间,所以他的mm设置为NULL,但是由于页目录的地址保存在mm结构中,从其他进程切换到这个内核态进程是,调度器可能需要切换页表,为此增加了一个active_mm,对于mm为NULL的内核线程,就借用其他进程的mm_struct,也就是说把它的active_mm指向其他进程的mm结构。当进行进程切换时,统一使用active_mm就可以了,但是其他进程不是有独立的页表吗?由于内核态线程只使用内核地址空间,因此这不会有问题。
用户态进程都有一个可执行文件,start_code,end_code分别指向该进程代码段起始地址和结束地址,start_data,end_data指向进程数据段的起始地址和结束地址,start_stack指向进程的堆栈起始地址,start_brk指向进程的堆(heap)的起始地址,arg_start,arg_end指向进程的命令行参数,env_start,env_end指向该进程的环境变量。这个进程的虚拟地址空间布局如图所示:
用户可以通过cat /proc/pid/maps文件看到进程的虚拟地址空间分配情况,当运行一个可执行文件时,可执行文件的装载器会根据这个布局加载可执行文件。用户态虚拟地址空间的顶端地址为3GB,这里空出一小片区域不映射,接下来是进程的环境变量,再接下来是命令行参数,这是装载器放置好的,再往下就是动态库,对于某些库,只有一份代码存在物理内存中,但是被映射到了好几个进程的虚拟地址空间中。之后,就是进程的堆栈,对于C程序来说,argc,argv还有main函数的返回地址压入堆栈后,就调用main()函数。堆栈从高地址向低地址增长。从低地址0x80000000开始,是代码段和数据段,再往上就是堆heap的起始地址,堆从低地址向高地址增长,我们知道malloc()这一类函数就是从堆中分配内存的。这里堆和栈都是动态变化的,他们一个从上往下增长,另一个从下往上增长。对于堆栈操作,当进程访问到一个没有被映射的虚拟地址时,缺页中断会分配物理页面并建立映射。类似地,对于堆操作,当分配到物理内存后,就映射到堆的虚拟地址空间上。由于进程对堆和栈的大小都有限制,因此缺页中断可以保证它们在虚拟地址空间上不会相交。
http://blog.csdn.net/liujun01203/article/details/5862888
- 进程的虚拟内存布局
- 应用程序运行时的虚拟内存布局 - 进程 - 线程
- 进程的虚拟内存
- linux 进程的虚拟内存
- CE6上的虚拟内存布局
- 进程和虚拟内存的列子
- Linux 进程虚拟内存的问题
- 进程虚拟内存
- 进程虚拟内存
- 进程虚拟内存空间---线性区的数据结构
- 测试进程占用的虚拟内存大小
- 进程最大可访问的虚拟内存空间
- 进程的虚拟内存,物理内存,共享内存
- 进程的虚拟内存,物理内存,共享内存
- 进程的虚拟内存,物理内存,共享内存
- arm Linux虚拟内存布局
- arm linux虚拟内存布局
- [原创翻译]WinCE5与WinCE6的虚拟内存布局(wwfiney@ARMCE)
- HttpClient 4.3教程(转载)
- java网络编程(一)单线程网络编程
- win7:windows update问题,无法检查更新
- 如何访问google.com(而不是google.com.hk)
- 路何去何从-第三方Oracle服务商
- 进程的虚拟内存布局
- c/c++多线程编程与无锁数据结构漫谈
- 速度环加位置环进行电机控制
- online_judge_1163
- Calabash Android 简介
- 自定义Dialog以及按钮事件监听
- mac下python连接mysql数据库遇到的问题及解决
- Android 4.2中对WebView.addJavascriptInterface()的修改
- 安装Kali Linux操作系统Kali Linux无线网络渗透