虚拟地址空间大小
32位
0——2^32(0-4GB)
每个进程都有0-4GB的空间
16进制表示:
一个页面4k。
所以一个进程可以划分
页面(逻辑页面)
堆如果不malloc是不会进行初始化的,如果向堆区申请32个字节的,他会初始化堆,一次性拿出若干个大小的空间,各种多大的多大的分一块,缓存起来。申请32个字节,他分配给你,你free掉,也是还给这个缓存。就像一个批发商店。
用户只有3G,0,1,n,m代表页面号(逻辑页面)。
一般我们很少用到大内存空间。
我们4G的意义:就是一个上限,一个进程的地址空间最大可以达到4G。
严格来说是3G,内核空间使用1G。
内核空间是所有用户空间共享通用的!!!,只有1个!!!
超过3G的程序一次性装载进来32位的是不可能的,超过了,用户只有3G空间,再除去代码段数据段,还有最下面的空着的空间。
我们有a程序,b程序,c程序,那是不是:我们运行a程序,3G,b程序,3G,c程序3G???3个程序运行起来9G???
只是最大允许使用3G,其实程序远远用不到那么多。但是如果程序真的那么大,2G多,也是可以的。也真的存在。实际情况比较少见。
逻辑页面和物理页面
逻辑页面最终要映射到物理页面,通过页表来描述关系。
我们并不知道物理内存什么时候在什么地方是空闲的。我们就找,哪里是空闲的,就在哪里落脚。
但是我们的逻辑(逻辑页面)是不会变的,是可以指定的(逻辑页面页号,逻辑顺序),而物理地址是我们没办法指定的。我们printf打印出来的都是逻辑地址。
逻辑上是相连续的,但是在物理页面上可以是不相连的。按照查表的方式。
前一个页面的地址大小加上偏移字节数=地址
虚拟内存
把暂时不用的内存块换出来。
可以运行比物理内存大的程序。
进程控制块PCB
mm_struct
pgd的作用是建一个页表,可以分2级,3级页表。
线性区间
就是虚拟地址空间
每个vm_area_struct描述一个线性区间
我们只是一部分一部分去使用。 一个堆区就是一个线性区间。一个数据段,共享库就是一个线性区间。
各个线性区间串起来就是一个链表
s代表起始vm_start,e代表末尾vm_end。
每条线开始在一个整页
一个区间可以被划分成多个页面
PCB记录着哪些区间由我们使用的,被使用的
代码段也可以分很多个区。我们定义的。实际上不止上图4个区。
只是一般划分成上面4个区间。但是会拆成多个。
实际上是分级的页表(具体详细见我的另外一篇博客(虚拟内存))