Java-操作系统-10
1.50 谈谈内存映射文件。
参考回答
- 内存映射(mmap) 是一种内存映射文件的方法,即将一个文件或者其他对象映射到进程的地址空间,实现文件磁盘地址和应用程序进程虚拟地址空间中一段虚拟地址的一一映射关系。实现这样的映射关系后,进程就可以采用指针的方式读写操作这一段内存,而系统会自动回写藏页面到对应的文件磁盘上。应用程序处理映射部分如同访问主存。

- mmap内存映射原理
(1)线程启动映射过程,并在虚拟地址空间中为映射创建虚拟映射区域。
先在用户空间调用库函数mmap,并在进程当前进程的虚拟地址空间中,寻找一段空闲的满足要求的连续虚拟地址作为内存虚拟映射区域,对此区域初始化并插入进程的虚拟地址区域链表或树中。
(2)系统在内核空间调用内核函数mmap,实现文件物理地址和进程虚拟地址之间的一一映射关系。
(3)进程发起堆这片映射空间的访问
进程读写操作访问虚拟地址,查询页表,发现这一段地址并不在内存的物理页面上,因为虽然建立了映射关系,但是还没有将文件从磁盘移到内存中。由此发生缺页中断,内核请求从磁盘调入页面。调页过程先在交换缓存空间(swap cache)中查找,若没有则通过nopage函数把缺失页从磁盘调入内存。之后进程会对其做读写操作,若写操作改变了页面内容,一段时间后系统会自动回写脏页面到磁盘中。(修改过的脏页面不会立即更新到文件中,可以调用msync来强制同步,写入文件)
- mmap和分页文件操作的区别
区别在于分页文件操作在进程访存时是需要先查询页面缓存 (page cache) 的,若发生缺页中断,需要通过inode定位文件磁盘地址,先把缺失文件复制到page cache,再从page cache复制到内存中,才能进行访问。这样访存需要经过两次文件复制,写操作也是一样。总结来说,常规文件操作为了提高读写效率和保护磁盘,使用了页缓存机制。这样造成读文件时需要先将文件页从磁盘拷贝到页缓存中,由于页缓存处在内核空间,不能被用户进程直接寻址,所以还需要将页缓存中数据页再次拷贝到内存对应的用户空间中。但mmap的优势在于,把磁盘文件与进程虚拟地址做了映射,这样可以跳过page cache,只使用一次数据拷贝。
1.51 谈谈虚拟内存模型。
参考回答
虚拟内存分成五大区,分别为栈区、堆区、全局区(静态区)、文字常量区(常量存储区)、程序代码区。五大区特性如下:
- 栈区(stack): 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。
- 堆区(heap): 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表。
- 全局区(静态区)(static):全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。程序结束后由系统释放。
- 文字常量区(常量存储区) :常量字符串就是放在这里的。 程序结束后由系统释放。这是一块比较特殊的存储区,他们里面存放的是常量,不允许修改。
- 程序代码区:存放函数体的二进制代码。
答案解析
以32位的操作系统为例,32位的操作系统每个进程对应的虚拟内存为4G(2的32次方),其中内核区1G,用户区3G。结构图如下:

1.52 什么是物理内存和虚拟内存,为什么要有虚拟内存?
参考回答
物理内存及虚拟内存定义
物理内存是相对于虚拟内存而言的。物理内存指通过物理内存条而获得的内存空间,而虚拟内存则是指将硬盘的一块区域划分来作为内存。内存主要作用是在计算机运行时为操作系统和各种程序提供临时储存。
为什么要有虚拟内存
在早期的计算机中,要运行一个程序,会把这些程序全都装入内存,程序都是直接运行在内存上的,也就是说程序中访问的内存地址都是实际的物理内存地址。当计算机同时运行多个程序时,必须保证这些程序用到的内存总量要小于计算机实际物理内存的大小。 早期内存分配方法实例:
某台计算机总的内存大小是 128M ,现在同时运行两个程序 A 和 B , A 需占用内存 10M , B 需占用内存 110 。计算机在给程序分配内存时会采取这样的方法:先将内存中的前 10M 分配给程序 A ,接着再从内存中剩余的 118M 中划分出 110M 分配给程序 B 。这种分配方法可以保证程序 A 和程序 B 都能运行,但是这种简单的内存分配策略问题很多。如下图:
<https://static.nowcoder.com/images/activity/2021jxy/java/img src=" alt="早期内存分配截图" style="zoom:80%;" />
早期内存分配方法
早期的内存分配方法存在如下几个问题(为什么要有虚拟内存的原因):
问题 1 :进程地址空间不隔离。由于程序都是直接访问物理内存,所以恶意程序可以随意修改别的进程的内存数据,以达到破坏的目的。有些非恶意的,但是有 bug 的程序也可能不小心修改了其它程序的内存数据,就会导致其它程序的运行出现异常。这种情况对用户来说是无法容忍的,因为用户希望使用计算机的时候,其中一个任务失败了,至少不能影响其它的任务。
问题 2 :内存使用效率低。在 A 和 B 都运行的情况下,如果用户又运行了程序 C,而程序 C 需要 20M 大小的内存才能运行,而此时系统只剩下 8M 的空间可供使用,所以此时系统必须在已运行的程序中选择一个将该程序的数据暂时拷贝到硬盘上,释放出部分空间来供程序 C 使用,然后再将程序 C 的数据全部装入内存中运行。可以想象得到,在这个过程中,有大量的数据在装入装出,导致效率十分低下。
问题 3 :程序运行的地址不确定。当内存中的剩余空间可以满足程序 C 的要求后,操作系统会在剩余空间中随机分配一段连续的 20M 大小的空间给程序 C 使用,因为是随机分配的,所以程序运行的地址是不确定的。
虚拟内存的实现(可以在页式或段式内存管理的基础上实现)
(1)在装入程序时,不必将其全部装入到内存,而只需将当前要执行的部分页面或段装入到内存,就可让程序开始执行;
(2)在程序执行过程中,如果需执行的指令或访的数据尚未在内存(称为缺页或缺段),则由处理器通知操作系线将相应的页面或段调入到内存,然后继续执订程序;
(3)另一方面,操作系统将内存中暂时不用的页面或段调出保存在外存上,从而腾出更多空困空间存放将要装入的程字以及将要调入的页画或段。
虚拟技术基本特征:大的用户空间(物理内存和外存相结合形成虚拟空间)、部分交换(调入和调出是对部分虚拟地址空间进行的)、不连续性(物理内存分配的不连续,虚拟地址空间使用的不连续)。
答案解析
分段
为了解决早期内存分配方式带来的问题,人们想到了一种变通的方法,就是增加一个中间层,利用一种间接的地址访问方法访问物理内存。按照这种方法,程序中访问的内存地址不再是实际的物理内存地址,而是一个虚拟地址,然后由操作系统将
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
本面试宝典均来自校招面试题目大数据进行的整理