操作系统中的内存管理:内存压缩(Memory Compaction)技术
字数 1167 2025-11-21 14:33:38
操作系统中的内存管理:内存压缩(Memory Compaction)技术
1. 问题背景:内存碎片
在操作系统中,进程申请和释放内存后,空闲内存可能被分割成许多不连续的小块,称为内存碎片。这分为两种:
- 外部碎片:内存块之间的空闲区域太小,无法分配给新进程。
- 内部碎片:已分配的内存块中未被使用的部分(如分配时按固定大小分页,但进程实际需求小于页大小)。
内存压缩主要解决外部碎片问题。
2. 内存压缩的核心思想
内存压缩通过移动已分配的内存块,将分散的小空闲区域合并成一个大的连续空闲区域,从而满足新进程的大内存需求。例如:
初始内存布局:[进程A][空闲][进程B][空闲][进程C]
压缩后布局:[进程A][进程B][进程C][大块连续空闲]
3. 内存压缩的步骤(以连续内存分配为例)
步骤1:暂停进程运行
- 压缩过程中需要修改内存地址映射,因此需暂停所有进程,避免地址访问错误。
步骤2:遍历内存块并标记可移动的进程
- 操作系统检查每个已分配的内存块(如进程的数据段、堆段),判断是否可移动:
- 动态分配的内存(如堆内存)通常可移动。
- 某些特殊内存(如DMA缓冲区)可能固定不可移动。
步骤3:移动内存块并更新地址映射
- 将可移动的内存块按顺序迁移到内存低地址端,逐步填充空闲区域:
- 复制原内存块内容到目标地址。
- 更新进程的页表或基址寄存器(如基址-界限寄存器的基址值)。
- 清除原内存块标记。
步骤4:合并空闲区域
- 移动完成后,所有空闲区域被合并到内存高端,形成连续大空闲块。
步骤5:恢复进程运行
- 进程从新地址继续执行,由于地址映射已更新,进程无感知(透明性)。
4. 关键问题与挑战
问题1:地址更新如何保证正确性?
- 硬件依赖:
- 若使用基址寄存器,只需修改基址值(需硬件支持重定位)。
- 若使用页表,需更新页表项中的物理页号,并刷新TLB(快表)避免旧映射缓存。
问题2:压缩时机如何选择?
- 两种策略:
- 主动压缩:当外部碎片超过阈值时触发(如空闲内存总量足够但无连续大块)。
- 被动压缩:在内存分配失败时触发(如请求连续100KB,但最大空闲块只有80KB)。
问题3:移动内存的开销如何降低?
- 优化方向:
- 选择部分内存块移动(如仅移动阻碍合并大空闲块的关键进程)。
- 与页面置换结合(如将很少访问的页面换出到磁盘,减少移动量)。
5. 实际应用场景
- 早期操作系统(如Windows 98)使用内存压缩应对物理内存不足。
- 嵌入式系统中常见于实时内存管理(如RTOS的堆内存整理)。
- 现代系统更多依赖分页机制解决外部碎片(如页式内存管理天然避免外部碎片),但内存压缩仍用于特定场景(如Java虚拟机的垃圾回收中的内存整理)。
6. 总结
内存压缩通过移动内存块合并空闲区域,直接解决外部碎片问题,但需付出暂停进程和复制内存的开销。其实现依赖硬件地址转换机制(如重定位寄存器或页表),并在内存分配策略中权衡效率与响应速度。