目录
1.环境变量
1.1概念
保存了当前程序运行环境参数的变量
1.2优点
即时生效;让运行环境配置更加灵活;通过环境变量可以给运行的程序传递数据。终端shell中的变量其实有两种:环境变量、普通变量。环境变量具有进程之间的继承特性;普通变量没有。
1.3接口
char* getenv(char* name);
1.4指令
env:查看所有环境变量
set: 查看所有变量
echo:打印指定内容(可以是变量内容)到终端显示
export:声明一个变量为环境变量
unset:删除一个变量
1.5在程序中访问环境变量
1.getenv接口
2.main函数第三个参数 main(int argc,char* argv[],char* env[])
3.全局变量:extern char** environ;
2.程序地址空间
2.1内存地址
内存地址:对内存区域的编号(以字节为单位)。程序地址空间更应该称作:进程地址空间,因为运行起来的程序才会占据内存。在一个进程中,所访问到的所有的变量的地址都是一个虚拟地址(并不是真正的物理内存的地址)。
进程并不直接访问物理地址,而是通过访问虚拟地址,进行映射访问物理地址的方式进行。
目的:1.实现数据在物理内存上的离散式存储,提高碎片化内存利用率
2.实现内存访问控制
2.2实质
程序地址空间,其实是操作系统为每个进程描述的一个虚拟的地址空间,进程中每个变量的地址其实都是虚拟地址,虚拟地址经过页表映射之后,得到物理地址,进而访问物理内存 。
虚拟地址空间是一个结构体:linux下是mm_struct,系统通过mm_struct向每个进程描述了一个虚拟的,连续的,完整的,线性的地址空间。
2.3好处
1.每个进程都有一个完整独立的虚拟地址空间,则地址可以随便使用,不用担心冲突(地址管理更加方便)
2.经过页表映射可以将数据存储在物理内存的任意位置,实现数据的离散式存储,提高内存利用率
3.在进行页表映射之后可以进行访问权限的控制
2.4内存管理方式
2.4.1分段式内存管理
分段式内存管理:将一个整体的地址空间划分为多个段(代码段,数据段,堆区,栈......)
作用:更加利于编译器对于地址的管理
重要的两个要素:段表,虚拟地址组成
虚拟地址组成:段号,段内的偏移量
段表:是一种数据结构,其中描述的信息,段号,物理内存的一个起始地址
通过段号找到段表项,得到一块物理内存的起始地址,物理内存起始地址+偏移量就是实际数据内存存储在物理内存中的位置
2.4.2分页式内存管理
分页式内存管理:将一个整体的地址空间划分为大量的小的分页page(当前一般默认都是4096字节为一页)
作用:实现数据的离散存储,提高内存看利用率
两个关键要素:页表+虚拟地址组成
页表:页号,物理内存块起始地址,缺页中断位,访问权限位......
虚拟地址组成:页号+页内偏移
通过虚拟地址中的页号,在页表中找到相应的页表项,得到了一个物理内存块的起始地址。加上页内偏移就是实际的访问位置。
2.4.3分页式内存管理与分段式内存管理的不同
应用方向不同,分段式利于地址管理,分页式更倾向于碎片化管理,提高内存利用率以及内存访问控制
2.4.4段页式内存管理
段页式内存管理:先将地址空间进行分段,然后在每个分段内使用分页进行管理(集合了分段式和分页式的优势)
2.4.5例题
某计算机主存地址空间大小为256 MB, 按字节编址。虚拟地址空间大小为 4 GB,采用页式存储管理,页面大小为 4 KB, TLB(快表)采用全相联映射,有 4 个页表项, 内容如下表所示。
| 有效位 | 标记 | 页框号 | ... |
| ------ | ------ | ------ | ---- |
| 0 | FF180H | 0002H | ... |
| 1 | 3FFF1H | 0035H | ... |
| 0 | 02FF3H | 0351H | ... |
| 1 | 03FFFH | 0153H | ... |
则对虚拟地址03FF F180H 进行虚实地址变换的结果是(A)。
A.015 3180H
B.003 5180H
C.TLB 缺失
D.缺页
解:虚拟地址空间大小:4*1024*1024*1024
分页式管理:将整个虚拟地址空间划分为大量的页面,每个页面大小为4kb:4*1024
当前地址空间共被划分了:2^20个页面----1024*1024,页表项有2^20个,
虚拟地址组成分为页号+页内偏移,一个页号对应了一个页表项,则页号也有2^20个,4GB地址空间,一个虚拟地址32个比特位,页号从0~2^20进行编号,占据了地址中的20个比特位,意味着一个虚拟地址中,高20位是页号,剩下的12位是页内偏移。03FFF180中高20位是页号,剩下12位是页内偏移,则页号:03FFF 页内偏移:180,这个页号对应的页表项中记录的物理块起始地址:0153,+页内偏移180,得到0153180H,这就是物理地址
2.4.6访问权限位
访问权限位:标记当前的地址能够进行什么样的操作
比如:1. 0号地址,也就是NULL,这个地址既不可读也不可写,因此一旦解引用或者修改则会内存访问错误。
2.const修饰的常变量,具有常性,其实就是访问权限上只读
3.代码段的所有地址,都是只读的
2.4.7缺页中断
缺页中断:当进程要访问一块内存的时候,经过页表映射的时候发现缺页中断为被置位(这个地址原先的数据现在不在内存中),则触发缺页中断。
2.4.8内存交换
内存交换:一个程序运行要占据大量内存,但是物理内存是有限的,意味着内存总有耗尽的时候,因此产生了一些需要:按照某种规则将内存中的某些数据从内存中移出去,放到硬盘上存起来,然后腾出的内存供当前程序使用。当我们要访问的数据刚好是被移出去的数据时,就会触发缺页中断,缺页中断后,就需要重新进行内存置换,将数据从交换区置换到内存中进行访问。
内存置换算法:内存不够的时候,把哪些数据移出去放到交换区上存储
典型算法:LRU--最久未使用; LFU--最少未使用
一旦产生大量的内存置换,则运行效率会大大降低,因为硬盘的数据交互吞吐量是很小的
交换分区应该设置为多大:没有统一的说法,32G内存以内通常都是内存的两倍大小
交换分区:这是安装系统的时候进行设定好的,硬盘一部分被划为交换分区,一部分被划为文件系统去(文件存储)