多线程面试题

虚拟内存技术

1.进程可以操作连续的内存空间

虚拟内存为每个进程提供了一个连续的、独立的虚拟地址空间。这意味着,从进程的视角来看,它拥有一块连续的内存区域,即使这些内存在物理内存中是分散存储的。这样做有几个好处:

  • 简化编程:程序员可以不用担心内存碎片化的问题,编程模型变得简单。
  • 增强安全性和稳定性:每个进程都有自己的地址空间,一个进程的错误(如访问无效内存)不会直接影响到其他进程。

2. 可以扩大物理内存范围,使用磁盘作为扩展

虚拟内存允许操作系统使用硬盘空间来模拟额外的RAM,这被称为”交换空间”(swap space)或”分页文件”(paging file)。这意味着即使物理RAM已经全部使用,系统仍然可以继续运行,通过将不活跃的内存页移到磁盘上来释放物理RAM空间。这个特性有几个重要的应用:

  • 允许更多的程序同时运行:通过交换不常用的数据到磁盘,可以在有限的物理内存中运行更多的应用程序。
  • 实现内存过载:即使应用程序使用的内存总量超过了物理内存的大小,操作系统也能够通过虚拟内存机制来支持这种过载,虽然这可能会降低性能。

实现原理

  • 分页:虚拟内存空间和物理内存空间被分割成固定大小的块,称为”页”。操作系统维护一张页表来记录每个虚拟页和物理页之间的映射关系。
  • 页表:每当进程访问其虚拟内存时,操作系统的内存管理单元(MMU)会查找页表,将虚拟地址转换为相应的物理地址。如果请求的虚拟页不在物理内存中(称为”缺页”),操作系统会从磁盘中加载该页到物理内存中,并更新页表。

虚拟内存技术极大地增加了计算机系统的灵活性和复杂性,使得操作系统能够更有效地管理有限的物理资源,同时也为应用程序提供了更大、更稳定的工作空间。

mmap

基本概念

  • 虚拟地址空间

    每个进程都有虚拟地址空间,且进程和进程之间的地址是独立的

    进程看到的都是操作系统虚拟出来的地址空间,但是虚拟地址最终还是要映射在实际的物理内存地址上进行操作的

  • 内存映射

    通过mmap将文件或设备使用到的物理地址映射到进程的虚拟地址空间,通过返回的指针即可直接操作到物理地址上的数据

    底层是通过页表来实现虚拟地址 –> 物理地址的映射,每个进程都有自己的页表,来管理地址的映射

谁来使用页表呢?MMU(内存管理单元),它来做地址的转换

映射关系

  • 虚拟内存系统将虚拟地址空间(程序使用的地址)映射到物理内存地址上。这个映射是动态进行的,由操作系统的内存管理单元(MMU)负责。
  • 每个进程都有自己独立的虚拟地址空间,这个地址空间通过操作系统的内存管理机制映射到共享的物理内存上。

物理内存扩展

  • 当物理内存(RAM)不足以容纳所有当前活跃的进程时,虚拟内存系统会使用硬盘上的一部分空间(称为交换空间或分页文件)作为内存使用。这意味着部分数据和代码可以从物理内存移动到磁盘上,从而为其他更需要的数据腾出空间。
  • 这个过程通常称为“分页”(paging)或“交换”(swapping),它允许操作系统有效地管理有限的物理内存资源,确保系统的运行。

磁盘空间作为内存空间

  • 通过虚拟内存系统,确实可以将磁盘空间“视作”内存空间来使用。当然,由于磁盘访问速度远低于RAM,所以操作系统会尽量保持频繁访问的数据在物理内存中。
  • 这种机制使得每个进程看起来都有比实际物理内存更多的内存可用。但是,过度依赖虚拟内存(特别是当物理内存经常不足,导致频繁的磁盘读写)可能会显著影响系统性能,这种现象称为“内存过度交换”(thrashing)。

操作mmap返回指针的流程示意图:

  1. 使用mmap映射物理内存到进程的虚拟内存
  2. 会自动更新页表,添加新的虚拟内存到物理内存的映射页表项
  3. 当操作mmap返回的指针时,CPU能看到的是进程的虚拟地址,CPU获取到虚拟地址
  4. MMU通过该进程的用户空间页表查询到该虚拟地址对应的真实物理地址,然后告诉给CPU
  5. CPU无需切换到内核态,直接操作对应的物理地址上的数据

重要结构体

  1. task_struct(进程描述符)
    • 每个进程在Linux内核中都由一个task_struct结构体实例表示,这个结构体包含了进程的所有信息,包括进程状态、PID、父进程、进程的调度信息、打开的文件描述符、信号处理信息等。
    • task_struct中的mm字段是一个指向mm_struct结构体的指针,它描述了进程的虚拟内存布局。
  2. mm_struct(内存描述符)
    • mm_struct负责描述一个进程的虚拟地址空间。它包含了关于进程虚拟内存的所有信息,比如页表的基址、虚拟内存区域的列表(通过mmap字段维护的vm_area_struct链表)、进程的代码段和数据段的起止地址等。
    • mm_struct通过其mmap字段(一个指向vm_area_struct链表头的指针)管理着进程的所有虚拟内存区域。
  3. vm_area_struct(虚拟内存区域描述符)
    • vm_area_struct表示进程虚拟地址空间中的一个连续区域。每个这样的区域可能对应于物理内存中的页或者磁盘上的文件(例如,通过mmap映射的文件)。
    • 每个vm_area_struct包含区域的起始和终止虚拟地址(vm_startvm_end),以及指向相邻虚拟内存区域的指针(vm_nextvm_prev),构成了一个链表。

总结

  • 一个进程由task_struct描述。
  • task_struct中的mm字段指向mm_struct,描述进程的整个虚拟地址空间。
  • mm_struct通过mmap字段管理一个vm_area_struct链表,每个vm_area_struct描述虚拟地址空间中的一个连续区域。

零拷贝

零拷贝(Zero-copy)技术,因为我们没有在内存层面去拷贝数据,也就是说全程没有通过 CPU 来搬运数据,所有的数据都是通过 DMA 来进行传输的。

通过系统调用函数sendfile()


多线程面试题
http://example.com/2024/02/22/面试题/操作系统/
作者
Mrxiad
发布于
2024年2月22日
许可协议