—–要说到操作系统的堆与内存的管理的话,那内容真的是海了去了,从开始的地方就能不停的扩展,但内容的重要性也是不可言喻的,本片博客着重于总结以下三点:
- Linux的虚拟地址空间布局
- 堆和栈的管理,堆和栈的区别
中间会涉及到一些扩展的知识,但是不会细说!
开始的地方: 程序的内存布局
要说堆和内存管理,那么开始的地方不得不是程序的内存布局,即虚拟地址空间,下面贴出一张虚拟地址空间图(盗的图):
分析 : 这张图可以让我们很明显的看明白虚拟地址空间的布局(32位);
内核部分就不说了,能力不够 -_-||, 重要的是我们知道虚拟地址空间的高1G的空间是给了内核就可以了,当然这是Linux内核,windows默认给内核分配2G,当然也可以配成1G;(有兴趣的同学可以去了解一下中断,或者进程切换时,内核栈和用户栈的切换,是如何保护现场的),下面我们都默认内核只占高1G的地址空间,而这1G的内核空间则是所有进程共享的,也就是那句话,每个进程都有4G的虚拟地址空间,但是其中的1G是所有进程共享的内核空间,而剩余的3G空间则是所有进程私有的用户地址空间,程序运行在内核空间和用户空间时的状态又被称为内核态和用户态,在内核态和用户态的运行级别是不同的,也就是权限是不同的,什么时候会进入内核态? 一般中断的时候会进入内核态运行,而中断又分为硬件中断和软中断,硬件中断,比如说你在键盘上输入的时候就是硬件中断,处理过程–保护现场–硬件处理–得到中断向量码–查找中断向量表–执行中断向量子程序–恢复现场;软件中断,比较常见的就是我们调用系统调用的时候,感觉不能扯远了,关于中断都是学校汇编课本学习的; 关于这块的内容建议参考**《程序员自我修养》**12章; 留一个问题,为什么要有内核态和用户态?
继续下一个,处于内核空间和栈之间的是环境变量和命令行参数,这些是在执行main函数之前就放好的,关于环境变量,在Linux下,输入env查看环境变量,set 查看所有变量,export 将普通变量变为环境变量,环境变量是会被子进程继承的,关于验证这一点其实也很简单 : 你在Linux命令行上设置一个普通变量,test=’aaaa’; 查看变量: echo $test; 此时test 是个普通变量;你用env | grep test 是找不到的,如果你用set | grep test 就可以看到设置的变量, 现在想要让test变为环境变量: export test; test变为环境变量; 现在就是验证子进程是否会继承环境变量了,很简单,命令行输入bash就会是一个子bash了,载看看test的值还在不在,退出子bash 按 ctrl+d