当前位置: 首页高频题加分模版训练问题详情 【操作系统专题】内存相关问题 本问题对应的项目链接:高频题回答模版训练 PS:这块问的也比较简单 1、虚拟内存了解吗?为啥要有虚拟内存呢? 2、虚拟内存和物理内存有啥区别? 3、讲一讲内存分页、分段?页表呢?
共以下 1 个回答
1、虚拟内存了解吗?为啥要有虚拟内存呢?
虚拟内存其实是处在进程和物理内存的中间层,它为每个进程提供了一个连续,完整的地址空间,实际上这块空间是由多个物理内存碎片组成的,并且还有一部分暂时存储在外部磁盘上,将内存扩展到了硬盘空间。这样以来,应用程序就可以访问比实际物理内存容量更大的地址空间,从而使更大的程序可以运行在计算机上。
除此之外,虚拟内存可以控制进程对物理内存的访问,隔离不同进程的访问权限,提高系统安全性。
2、虚拟内存和物理内存有啥区别?
物理内存就是计算机真实的内存容量,而虚拟内存是在物理内存之上做了一层抽象,将磁盘上的一部分空间加上整个物理内存构成虚拟内存空间。物理内存的空间是所有进程都共享的,而虚拟内存的空间是每个进程都独有的,但进程访问的虚拟内存地址最终还带映射到具体的物理内存地址上,这个操作交由操作系统的 MMU 来管理。也就是说,进程只管访问自己的虚拟内存空间,MMU 会进行从虚拟地址到物理地址的翻译工作,如果物理地址已经在内存就直接访问,如果是在磁盘,那就会发生缺页中断,将所缺的页先加载进内存,再进行访问。
这其中还需要考虑如果内存已经满了,但现在需要加载新的页到内存,此时应该踢出哪些已经在内存的页呢?这就涉及到页面置换算法的设计了。
3、讲一讲内存分页、分段?页表呢?
内存分页和内存分段是操作系统管理虚拟地址与物理地址之间的关系提出的。最早提出的是内存分段,之后由于内存分段存在一定缺陷,又提出了内存分页这种方式,现在大多数操作系统都采用内存分页的方式管理内存。
内存分段就是将操作系统中的程序分成若干个逻辑分段,例如代码段,数据段,栈堆段等等,不同的段带有不同的属性。一个虚拟地址只需保存程序的段选择因子和段内偏移量,就能确定该程序对应的段所在的具体位置。它虽然解决了从虚拟地址到物理地址的具体该如何映射,但分段机制本身存在内存碎片,进而还会导致内存交换效率低的问题。
由于分段机制下的各个段可以根据实际需求分配内存,有多大需求就分配多大的段,不会存在内部碎片问题。但由于每个段的大小不固定,多个段加起来未必能恰好使用完所有的内存空间,段与段之间对存在小的 “内存缝隙”,这些不连续的小物理内存加起来可能是比较大的,会导致新的程序无法装载。解决的方法就是通过内存交换,重新整理物理内存,将这些不连续的小物理内存给凑一起。具体就需要用到内存交换空间,在 Linux 中就是常见的 Swap 空间,在整理时先把物理空间中的一个段移到 Swap 空间中,然后再从 Swap 空间紧挨着上一个段移到物理空间中,这样就解决了内存碎片问题,但由于 Swap 空间在硬盘中,不可避免的需要访问磁盘,这个过程相比于内存来说是很慢的。而在分段机制下,内存碎片的发生频率又比较高,需要内存交换的频率就搞,但访问磁盘又慢,就会导致机器卡顿。
为了解决分段机制带来的问题,就推出了内存分页机制。具体来说,就是将整个虚拟空间和物理空间分成一个个小的页,每个页的大小为 4KB,然后再将这些页都排排号放在页表中,页表就交给 MMU 来管理。由于分页机制下的内存空间都是提前分配好的,页与页直接不存在 “内存缝隙”,也就不会有外部内存碎片问题。但分页机制下,分配内存的最小单位是一页,也就是 4KB,即使程序不足 4KB,我们也只能分配一个页来装载,也就是分页机制存在内部碎片问题。但这个碎片大小比起分段机制下动辄几百 MB 的碎片要好得多。
但简单的分页还有问题,在 32 位环境下,每个进程需要存储的页表大小为 4GB / 4KB * 4B = 4MB,如果有 100 个进程,光存储页表就需要占用 400MB 内存,这是非常大的数了,更别说 64 位环境了。这个问题的解决就是引入 ”多级页表“,将所有的页表每 1024 个凑成一个大的页表项,这样 4GB 的内存可以刚好凑成 1024 个大页表项,这些大页表项刚好可以只用一个页表存储,这个页表就称为一级页表,每个一级页表项就对应一个二级页表,二级页表中存储的就是具体的 4KB 的页。然后再根据程序的局部性原理,假设大部分程序只会使用到 20% 的虚拟内存,那么每个进程此时只需存储一个一级页表 4KB,外加 20% 的二级页表,总共就是 4KB + 20% * 4MB = 0.8 MB,相比原先的一级分页需要存储 4MB,是一种巨大的节约。那么把二级分页再推广到多级分页,就可以发现页表占用的空间更少了,这主要归功于对局部性原理的充分利用。现在常见的 64 位系统一般是四级分页。