内存分配方式及内存碎片
什么是内存碎片?
内部碎片的产生:因为所有的内存分配必须起始于可被 4、8 或 16 整除(视 处理器体系结构而定)的地
址或者因为 MMU 的分页机制的限制,决定内存分配算法仅能把预定大小的内存块分配给客户。假设当某个
客户请求一个 43 字节的内存块时,因为没有适合大小的内存,所以它可能会获得 44 字节、48 字节等稍大一
点的字节,因此由所需大小四舍五入而产生的多余空间就叫内部碎片。
外部碎片的产生: 频繁的分配与回收物理页面会导致大量的、连续且小的页面块夹杂在已分配的页面中间,
就会产生外部碎片。假 设有一块一共有 100 个单位的连续空闲内存空间,范围是 0~99。如果你从中申请一
块内存,如 10 个单位,那么申请出来的内存块就为 0~9 区间。这时候你 继续申请一块内存,比如说 5 个单
位大,第二块得到的内存块就应该为 10~14 区间。如果你把第一块内存块释放,然后再申请一块大于 10 个单
位的内存块,比 如说 20 个单位。因为刚被释放的内存块不能满足新的请求,所以只能从 15 开始分配出 20
个单位的内存块。现在整个内存空间的状态是 0~9 空闲,10~14 被占用,15~24 被占用,25~99 空闲。其中
0~9 就是一个内存碎片了。如果 10~14 一直被占用,而以后申请的空间都大于 10 个单位,那么 0~9 就 永远用
不上了,变成外部碎片。
简单介绍程序内存分配方式:
内存分配方式主要有连续型分配方式和非连续型分配方式,顾名思义,连续型分配方式就是分配连续的
空间,非连续型分配方式就是分配非连续的内存空间。
连续型分配内存方式:
单一连续分配:
最简单的分配方式,采用覆盖技术。优点是无外部碎片,缺点是只能用于单用户、有内部碎片、存储利
用率低。
固定分区分配:
最简单的多道程序存储管理方式,它将用户内存空间划分为若干个固定大小(可以相等,也可以不等,
同为 4 的倍数或其他),每个分区只装入一道作业。当有空闲分区的时候,就从作业队列里选择适当大小的
作业装入该分区。为便于内存分配,通常将分区按大小排队,并为之建立一张分区说明表,其中各项包括每
个分区的起始地址,大小及状态(是否被分配)。
无外部碎片,但是无法实现多进程共享一个主存区。
动态分区分配:
不预先划分内存,在程序装入内存时,根据进程的大小动态地建立分区,并使得分区的大小正好适合进
程的需要,因此系统中分区的大小和数目是可变的。
动态分区分配内存方式刚开始是很好地,但是,之后会导致内存出现很多的小的内存块,也就是外部碎
片。外部碎片可以通过紧凑来解决,就是操作系统不时地对进程进行移动和整理。但是需要动态重定位寄存
器的支持。
动态分区分配在当系统有很大的内存块的时候,分配内存必须要有一个策略。
1)首次适应:地址递增,顺序查找,第一个能满足的即分配给进程。
2)最佳适应:容量递增,找到第一个能满足要求的空闲分区。
3)最坏适应:容量递减,找到第一个能满足要求的分区。
4)邻近适应:循环首次适应算法。
当一个进程发生缺页中断的时候,进程会陷入内核态,执行以下操作:
1、检查要访问的虚拟地址是否合法
2、查找/分配一个物理页
3、填充物理页内容(读取磁盘,或者直接置 0,或者啥也不干)
4、建立映射关系(虚拟地址到物理地址)