什么是内部碎片、外部碎片
外部碎片,是由于大量信息由于先后写入、置换、删除而形成的空间碎片。为了便于理解,我们将信息比作货物,将存储空间比作仓库来举例子。假设,我们有编号为1、2、3、4、5、6的6间仓库库房,前天送来了一大宗货,依次装入了1、2、3、4、5号仓库,昨天又因故将4号库房的货物运走了,那么数值上说我们还有两间空仓库的空间,但是如果这时候送来两间仓库容量的货物但要求必须连续存放的话,我们实际上是装不下的。这时的4、6号仓库,就成为一种空间的碎片。由于这样的原因形成的空间碎片,我们称之为外部碎片。
内部碎片,是由于存量信息容量与最小存储空间单位不完全相符而造成的空间碎片。还是沿用上面的例子,这次我们的6间仓库目前都是空置的,但是假设我们管理仓库的最小空间单位是间,今天运来了容量为2.5间仓库的货物,那也要占用我们1-3号3间仓库,尽管3号仓库还闲置着一半的空间,但是这半间仓库已经不能再利用了(因为是以间为最小单位么);这时,我们的仓库中就形成了半间仓库的空间碎片,仓库的有效容量只剩下3间仓库了。
【外部碎片】
外部碎片指的是还没有被分配出去(不属于任何进程),但由于太小了无法分配给申请内存空间的新进程的内存空闲区域。
外部碎片是出于任何已分配区域或页面外部的空闲存储块。这些存储块的总和可以满足当前申请的长度要求,但是由于它们的地址不连续或其他原因,使得系统无法满足当前申请。
多道可变连续分配
只有外部碎片。
【内部碎片】
内部碎片就是已经被分配出去(能明确指出属于哪个进程)却不能被利用的内存空间;
内部碎片是处于区域内部或页面内部的存储块。占有这些区域或页面的进程并不使用这个存储块。而在进程占有这块存储块时,系统无法利用它。直到进程释放它,或进程结束时,系统才有可能利用这个存储块。
单道连续分配
只有内部碎片。多道固定连续分配
既有内部碎片,又有外部碎片。
解决办法
作者:匿名用户
链接:https://www.zhihu.com/question/51836333/answer/145693402
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
首先,使用最原始的标记分配方法,系统需要维护一个简单的内存信息表:

当程序申请一个长度为3的内存空间后:

当程序再申请一个长度为2,以及长度为4的内存空间后:

此时,只剩1个可用空间。如果这时程序再来申请长度大于1的空间,就申请不了,也就是内存不够。现在,释放掉ID=2的空间:

我们发现,现在可用内存空间为3,但是,这3个空闲空间,并不是连续的。所以,如果程序现在申请长度为3的内存空间,同样会申请不了,会出现内存不够。业界把这种情况,称之为【内存碎片】。明明剩余有3个空间,却申请不了3个内存空间,这TMD扯蛋?于是,工程师们,发明了基于页面的内存管理方式:首先,把物理内存,按照某种尺寸,进行平均分割。比如我现在以2个内存单位,来分割内存,也就是每两个连续的内存空间,组成一个内存页:

接着,系统同样需要维护一个内存信息表:

现在,程序申请长度为3的内存空间,不过由于现在申请的最小单位为页面,而一个页面的长度为2,因此现在需要申请2个页面,也就是4个内存空间。你看,这就浪费了1个内存空间。

接着,程序再申请长度为1,长度为2的空间:

释放掉ID=2,内存页ID为3的那条内存空间信息:

现在,就出现了之前的情况:目前一共有4个内存空间,但是不连续。不过,因为现在是分页管理机制,因此,现在仍然可以继续申请长度为4的内存空间:

前面那种内存分配方式,虽然容易出现碎片,并且内存空间的利用率低,但是使用性能高,程序能直接从内存信息表获取内存地址,接着就可以直接按照地址来使用内存空间了。但下面这种分页的方式,程序需要记录的是内存页ID,每次使用时,需要从内存页ID翻译成实际内存地址,多了一次转换。而且这种模式,会浪费一些内存,比如上面申请3个内存空间,实际分配了2个页面共4个内存空间,浪费了1个内存空间。以上就是基本原理,实际系统中会做非常多的优化。目前各种主流操作系统都是分页的方式,因此你不需要太关心碎片。
现代计算机
中内存管理使用了基于虚拟内存的分段和分页机制,每一个进程看到的是4G(32位)或64TB(64位)的虚拟内存地址空间,一般情况下程序是用不完的。分页机制保证仅当程序需要储存修改数据的时候才会在真实的物理内存上获取多个4KB大小的不连续的页,且被初始化为全零,这些页作为虚拟内存上的映射,使用一个malloc,操作系统会在进程的虚拟内存分配表上标记那块区域已被使用,程序修改数据的时候才会在物理内存中开辟空间获取多个不连续的页,使用free,操作系统会删除内存分配表的记录,同时回收物理内存上的页。
使用malloc和free虽然会导致虚拟内存上碎片,但在物理内存上是不连续使用的,不会导致碎片。
在普通计算机上如果虚拟内存碎片太多无法分配,一般操作系统会告诉你进程无响应,重新打开程序即可,一般64TB空间不会出现这种情况;长时间运行的操作系统可能会有这种情况,此时重启即可。
碎片只会在虚拟内存中产生,是不会映射到物理内存上的。