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): 置换在「未来」最长时间不访问的页面。
  • 先进先出置换算法
  • 最近最久未使用的置换算法
  • 时钟页面置换算法
  • 最不常用置换算法
相关推荐
ZGG0031 小时前
MCP 02:MCP 的各类比对——和 Function Calling、A2A、Skill 到底什么关系
人工智能·后端·python
IT_陈寒1 小时前
Vite热更新突然失效?可能是这个配置在捣鬼
前端·人工智能·后端
JMchen1231 小时前
【Android 性能优化实战 60 讲】03 Perfetto 现代分析利器:SQL 查询 Trace 数据,微秒级定位函数 CPU 耗时
android·sql·性能优化·实战·源码分析·perfetto·启动优化
SelectDB技术团队2 小时前
统一全文检索与 SQL 分析:Apache Doris 日志分析实践
大数据·数据结构·后端·python·全文检索·doris·日志分析
程序员贺加贝2 小时前
报表大-IN-优化-一条-product_profile-超大-IN-SQL-背后的报表任务治理
java·spring boot·sql·性能优化·架构
霸道流氓气质2 小时前
Spring AI多模型路由与动态切换
java·后端·spring
艺杯羹2 小时前
全栈信创落地实录:基于银河麒麟V10与达梦数据库DM8的SpringBoot工业级适配指南
java·数据库·spring boot·后端·spring
学长毕业设计10 小时前
基于SpringBoot的公益基金管理系统(源码+文档+讲解视频)
java·spring boot·后端
东小西11 小时前
【SAA实战】第 3 篇 · 工具调用全攻略:把业务能力交给 Agent 自己调度
java·后端·spring
东小西11 小时前
【SAA实战】第 4 篇 · Agent 短期记忆:saver 让 Agent 跨轮记得住(threadId 隔离)
java·后端·spring