6.15 操作系统面试题 锁 内存管理

自旋锁

自旋锁加锁失败后,线程会忙等待,直到它拿到锁。

需要注意,在单核 CPU 上,需要抢占式的调度器(即不断通过时钟中断一个线程,运行其他线程)。否则,自旋锁在单 CPU 上无法使用,因为一个自旋的线程永远不会放弃 CPU。

当加锁失败时,互斥锁用「线程切换」来应对,自旋锁则用「忙等待」来应对。

如果你能确定被锁住的代码执行时间很短,就不应该用互斥锁,而应该选用自旋锁,否则使用互斥锁。

死锁发生条件是什么?

  • 互斥条件
  • 持有并等待
  • 不可剥夺条件
  • 环路等待
    资源有序分配法

银行家算法

银行家算法是最有代表性的避免死锁的算法。

分配给进程资源前,首先判断这个进程的安全性,也就是预执行,判断分配后是否产生死锁现象。通过不断检查剩余可用资源是否满足某个进程的最大需求,如果可以则加入安全序列,并把该进程当前持有的资源回收;不断重复这个过程,看最后能否实现让所有进程都加入安全序列。

介绍一下操作系统内存管理

操作系统设计了虚拟内存,每个进程都有自己的独立的虚拟内存,我们所写的程序不会直接与物理内打交道。

分页是把整个虚拟和物理内存空间切成一段段固定尺寸的大小。

虚拟地址与物理地址之间通过页表 来映射。

页表是存储在内存里的,内存管理单元 (MMU)就做将虚拟内存地址转换成物理地址的工作。

访问的虚拟地址在页表中查不到时,系统会产生一个缺页异常 ,进入系统内核空间分配物理内存、更新进程页表,最后再返回用户空间,恢复进程的运行。

分页不会有外部碎片,但会有内部碎片

页号+偏移量

讲一下段表?

虚拟地址也可以通过段表与物理地址进行映射的,分段机制会把程序的虚拟地址分成 4 个段,每个段在段表中有一个项,在这一项找到段的基地址,再加上偏移量。

虚拟地址是怎么转化到物理地址的?

在虚拟地址转换的过程中,通常会使用页表(Page Table)来进行映射。当程序访问一个虚拟地址时,MMU会将虚拟地址分解为页号和页内偏移量。

程序的内存布局是怎么样的?

  • 代码段,包括二进制可执行代码;
  • 数据段,包括已初始化的静态常量和全局变量;
  • BSS 段,包括未初始化的静态变量和全局变量;
  • 堆段,包括动态分配的内存,从低地址开始向上增长;
  • 文件映射段,包括动态库、共享内存等;
  • 栈段,包括局部变量和函数调用的上下文等。栈的大小是固定的,一般是 8 MB。

堆和栈的区别?

  • 堆是动态分配内存,由程序员手动申请和释放内存 ,通常用于存储动态数据结构和对象 。如果管理不当可能会导致内存泄漏或内存溢出 。堆通常比栈大,内存空间较大,动态分配和释放内存需要时间开销。
  • 栈是静态分配内存,由编译器自动 分配和释放内存,用于存储函数的局部变量和函数调用信息。遵循后进先出 的原则,变量的生命周期由其作用域决定 ,函数调用时分配内存,函数返回时释放内存。栈大小有限,通常比较小,内存分配和释放速度较快,因为是编译器自动管理。

fork()会复制哪些东西?

fork 阶段会复制父进程的页表(虚拟内存)

fork 之后,如果发生了写时复制 ,就会复制物理内存

当父进程或者子进程在向这个内存发起写操作 时,CPU 就会触发写保护中断 ,这个写保护中断是由于违反权限导致的,然后操作系统会在「写保护中断处理函数」里进行物理内存的复制 ,并重新设置其内存映射关系,将父子进程的内存读写权限设置为可读写,最后才会对内存进行写操作。

malloc 1KB和1MB 有什么区别?

如果用户分配的内存小于 128 KB,则通过 brk() 申请内存;

如果用户分配的内存大于 128 KB,则通过 mmap() 申请内存;

brk() 函数将「堆顶」指针向高地址移动,获得新的内存空间。

mmap() 系统调用中「私有匿名映射」的方式,在文件映射区分配一块内存

操作系统内存不足的时候会发生什么?

如果没有空闲的物理内存,那么内核就会开始进行回收内存的工作

OOM Killer 机制会根据算法选择一个占用物理内存较高的进程,然后将其杀死,以便释放内存资源

页面置换有哪些算法?

  • 最佳页面置换算法(OPT): 置换在「未来」最长时间不访问的页面。
  • 先进先出置换算法
  • 最近最久未使用的置换算法
  • 时钟页面置换算法
  • 最不常用置换算法
相关推荐
颜酱15 分钟前
# 02 | 搭骨架:用 LangGraph 编排 12 步工作流(思路)
前端·人工智能·后端
颜酱16 分钟前
02 | 搭骨架:用 LangGraph 编排 12 步工作流
前端·人工智能·后端
嘉伟桑1 小时前
Python调用电价API返回JSON示例:分时电价、现货电价和字段解析
后端
武子康2 小时前
Shippy:确定性工具、会话级 Sandbox 与 Live-Data Eval(4 类收敛 + 7 步实现方案 + 6 类评测指标)
前端·人工智能·后端
我叫黑大帅2 小时前
我为什么单一消费者的场景下,要用 Redis List 当消息队列?
redis·后端·面试
AskHarries2 小时前
文件上传系统
后端
止语Lab3 小时前
好的 DX 不等于少写代码——三种语言的摩擦力设计课
后端
吃饱了得干活3 小时前
别再手动解析 LLM 输出了!LangChain 四种结构化输出方案对比
后端·python·langchain
谷无姜3 小时前
为什么你的性能优化无效?可能是"木桶效应"在作祟
前端·性能优化
程序员天天困3 小时前
Arthas trace 命令怎么用?一行定位最慢那行代码
jvm·后端