三种fragmentation(internal, external, data)
摘自维基百科
内存按chunk分配,每个程序保留的chunk的大小和时间都不同。一个程序可以多次请求和释放memory chunk。程序一开始时,空闲内存有很多并且连续,随后大的连续的内存区域碎片化,变成更小的连续区域,最终程序无法获取大的连续的memory chunk。
1) Internal fragmentation = 分给程序的内存比它实际需要的多,多分的内存被浪费。
比如chunk一般是4, 8或16的倍数,请求23字节的程序实际可以获得24字节的chunk,未被使用的内存无法再被分配,这种分配叫fixed partitions。一个程序无论多么小,都要占据一个完整的partition。通常最好的解决方法是改变设计,比如使用动态内存分配,把内存空间的开销分散到大量的objects上,内存池可以大大减少internal fragmentation。
2) External fragmentation = 有足够的空闲内存,但是没有足够的连续空闲内存供分配。因为都被分成了很小的pieces,每个piece都不足以满足程序的要求。external指未使用的存储空间在已分配的区域外。这种情况经常发生在频繁创建、更改(大小)、删除不同大小文件的文件系统中。比起文件系统,这种fragmentation在RAM上更是一个问题,因为程序通常请求RAM分配一些连续的blocks,而文件系统可以利用可用的blocks并使得文件逻辑上看上去是连续的。所以对于文件系统来说,有空闲空间就可以放新文件,碎片化也没关系,对内存来说,程序请求连续blocks可能无法满足,除非程序重新发出请求,请求一些更小的分散的blocks。解决方法一是compaction,把所有已分配的内存blocks移到一块,但是比较慢,二是garbage collection, 收集所有无法访问的内存并把它们当作空闲内存,三是paging, 把物理内存分成固定大小的frames,用相同大小的逻辑内存pages填充,逻辑地址不连续,只要有可用内存,进程就可以获得,但是paging又会造成internal fragmentation。
3) Data fragmentation. 通常发生在向一个已有external fragmentation的存储系统中插入一个大的object的时候,操作系统找不到大的连续的内存区域,就把一个文件不同的blocks分散放置,放到可用的小的内存pieces中,这样文件的物理存放就不连续,读写就慢了,这叫文件系统碎片。消除碎片工具的主要工作就是重排block,让每个文件的blocks都相邻。