本文主要是介绍操作系统---内存管理,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
- 我们程序所使用的内存地址叫做虚拟内存地址;
- 实际存在硬件里面的空间地址叫做虚拟内存地址;
- 操作系统引入了虚拟内存,进程持有的虚拟地址会通过CPU芯片中的内存管理单元(MMU)的映射关系,来转换变成物理地址,然后通过物理地址访问内存;
- 操作系统管理虚拟地址与物理地址:内存分段和内存分页;
- 内存分段:程序由若干个逻辑分段组成的,如可由代码段、数据段、栈、堆等,不同的段有不同的属性,所以就用分段的形式把这些段分离出来;
- 分段机制下,虚拟地址和物理地址通过段选择因子和段内偏移量来映射;
- 内存分段所带来的问题:内存碎片、内存交换效率低下;
- 分段的好处是能产生连续的内存空间,但是会出现内存碎片和内存交换的空间太大的问题,由此产生了内存分页;
- 内存分页:分页是把整个虚拟和物理内存空间切成一段段固定尺寸的大小,这样一个连续并且尺寸固定的内存空间,我们叫做页,在Linux下,每一页的大小为4KB;
- 分页机制下,虚拟内存与物理内存通过页表来映射,MMU就做将虚拟地址转换成物理地址的工作;
- 当进程访问的虚拟地址在页表中查不到时,系统会产生一个缺页异常,进入系统内核空间分配物理内存,更新进程的页表,最后返回用户空间,回复进程的运行;
- 分页机制下,由于内存空间都是预先划分好的,也就不会像分段产生间隙非常小的内存,因此不会产生内存碎片;且内存释放也是以页为单位进行释放,也就不会产生无法给进程使用的小内存;
- 换入换出:如果内存不够,操作系统会把其它正在运行的进程中的 最近未使用 的内存页面给释放掉,也就是暂时写在硬盘上,称为换出,一旦需要的时候,在加载进来,称为换入,所以一次性写入硬盘的也只有少数的一个页或者几个页,不会花太多时间,内存交换的效率相对高;
- 分页使得我们在加载程序时,不再需要一次性都把程序加载到物理内存中,我们可以在进行虚拟内存和物理内存的页之间的映射之后,并不把页加载到物理内存中,而是在程序运行中,需要用到对应虚拟内存页里面的指令和数据时,再加载到物理内存中;
- 分页机制下,虚拟内存和物理内存通过页表和页内偏移进行映射;
- 多级页表虽然解决了空间上的问题,但是虚拟地址到物理地址的转换就多了几道转换的工序,这显然降低了这两个地址转换的速度,也就是带来了时间上的开销;
- 程序是有局部性的,即在某一段时间内,整个程序的执行仅限于程序中的某一个部分,相应地,执行所访问的存储空间也局限于某个内存区域;我们根据这一个特性,把最常访问的几个页表项存储到访问速度更快的硬件,在CPU芯片中,加入了TLB(页表缓存),存放上述所说的页表;
- 在CPU芯片中,封装了内存管理单元(MMU),它用来完成地址转换和TLB的访问与交互;有了TLB后,那么CPU在寻址时,会先查TLB,如果没找到,才会继续查常规的页表。TLB的命中率还是挺高的,因为程序最常访问的页就那么几个;
- 段页式内存管理:分段和分页组合使用;实现方式如下:
- 先将程序划分为多个有逻辑意义的段,也就是前面所说的分段机制;
- 接着再把每个段划分为多个页,也就是对分段划分出来的连续空间,再划分固定大小的页;
- 这样地址结构就由段号、段内页号、页内偏移三部分组成;
1、Linux内存管理?
- Linux主要采用的是页式内存管理,但同时也不可避免的涉及了段机制;
- Linux系统中的每个段都是从0地址开始的整个4GB虚拟空间,也就是所有的段的起始地址都是一样的。
2、在Linux操作系统中,虚拟地址空间的内部又被分为内核空间和用户空间;
- 32位系统,内核空间占用1G,位于最高处,剩下的3GB是用户空间;
- 64位系统,内核空间和用户空间都是128T,分别占据整个内存空间的最高和最低处,剩下的是未定义的;
3、虽然每个进程都各自有独立的虚拟内存,但是每个虚拟内存中内核空间,其实关联的都是相同的物理内存,这样进程切换到内核态后,就可以很方便的访问内核空间;
这篇关于操作系统---内存管理的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!