内存碎片 -- 描述一个系统中所有不可用的空闲内存。这些资源之所以仍然未被使用,是因为负责分配内存的分配器使这些内存无法使用。一个不断产生内存碎片的系统,不管产 生的内存碎片多么小,只要时间足够长,就会将内存用完。这种情况在许多嵌入式系统中,特别是在高可用性系统中是不可接受的。
输出结果如下:
当程序中mem2和mem4被释放后,就出现了2块内存碎片,如果后续没有再申请内存或者没有申请到这2片内存的话,内存碎片将一直存在。
由以上结果可以看出,内存申请时还是会使用之前的内存碎片的,只是会用不完造成较小的内存碎片。
内存碎片是如何产生的呢,做个小实验看看。
1.申请5个100k内存
2.释放其中2个
3.申请1个120k内存
4.再次申请2个100k内存
#include <stdlib.h>
#include <iostream>
using namespace std;
int main()
{
int * mem1;
int * mem2;
int * mem3;
int * mem4;
int * mem5;
int * mem6;
printf("sizeof(int) = %d\n", sizeof(int));
printf("malloc 100byte for mem1 to mem5.\n");
mem1 = (int *)malloc(sizeof(int) * 25);
printf("mem1.address = 0x%x\tmem1.point = 0x%x\n", &mem1, mem1);
mem2 = (int *)malloc(sizeof(int) * 25);
printf("mem2.address = 0x%x\tmem2.point = 0x%x\n", &mem2, mem2);
mem3 = (int *)malloc(sizeof(int) * 25);
printf("mem3.address = 0x%x\tmem3.point = 0x%x\n", &mem3, mem3);
mem4 = (int *)malloc(sizeof(int) * 25);
printf("mem4.address = 0x%x\tmem4.point = 0x%x\n", &mem4, mem4);
mem5 = (int *)malloc(sizeof(int) * 25);
printf("mem5.address = 0x%x\tmem5.point = 0x%x\n", &mem5, mem5);
printf("sizeof(int *) = %d\n", sizeof(mem1));
printf("free mem2 and mem4.\n");
free(mem2);
free(mem4);
printf("malloc 120byte for mem6.\n");
mem6 = (int *)malloc(sizeof(int) * 30);
printf("mem6.address = 0x%x\tmem6.point = 0x%x\n", &mem6, mem6);
printf("malloc 100 byte for mem2 and mem4 again.\n");
mem2 = (int *)malloc(sizeof(int) * 25);
printf("mem2.address = 0x%x\tmem2.point = 0x%x\n", &mem2, mem2);
mem4 = (int *)malloc(sizeof(int) * 25);
printf("mem4.address = 0x%x\tmem4.point = 0x%x\n", &mem4, mem4);
free(mem1);
free(mem2);
free(mem3);
free(mem4);
free(mem5);
free(mem6);
system("pause");
return 0;
}
输出结果如下:
sizeof(int) = 4
malloc 100byte for mem1 to mem5.
mem1.address = 0x2ef7c4 mem1.point = 0x984048
mem2.address = 0x2ef7b8 mem2.point = 0x9840d8
mem3.address = 0x2ef7ac mem3.point = 0x984168
mem4.address = 0x2ef7a0 mem4.point = 0x9841f8
mem5.address = 0x2ef794 mem5.point = 0x984288
sizeof(int *) = 4
free mem2 and mem4.
malloc 120byte for mem6.
mem6.address = 0x2ef788 mem6.point = 0x984318
malloc 100 byte for mem2 and mem4 again.
mem2.address = 0x2ef7b8 mem2.point = 0x9841f8
mem4.address = 0x2ef7a0 mem4.point = 0x9840d8
请按任意键继续. . .
当程序中mem2和mem4被释放后,就出现了2块内存碎片,如果后续没有再申请内存或者没有申请到这2片内存的话,内存碎片将一直存在。
从后续的打印可以看出,当再次申请mem2和mem4时,由于申请内存的大小和之前一致,系统又重新分配了这2片内存,内存碎片即被消除了。
(分析结果比较奇怪,还没想明白,为什么申请的内存不是连续的?局部对象mem1等从栈中分配的内存为什么也不是连续的?)
如果后续申请的内存大小和之前不一致呢?2种情况:
1.申请的内存比内存碎片大:如mem6一样,申请一片新内存,内存碎片依然存在。
2.申请的内存比内存碎片小:
printf("malloc 100 byte for mem2 and mem4 again.\n");
mem2 = (int *)malloc(sizeof(int) * 1);
printf("mem2.address = 0x%x\tmem2.point = 0x%x\n", &mem2, mem2);
mem4 = (int *)malloc(sizeof(int) * 1);
printf("mem4.address = 0x%x\tmem4.point = 0x%x\n", &mem4, mem4);
sizeof(int) = 4
malloc 100byte for mem1 to mem5.
mem1.address = 0x36fccc mem1.point = 0xa4048
mem2.address = 0x36fcc0 mem2.point = 0xa40d8
mem3.address = 0x36fcb4 mem3.point = 0xa4168
mem4.address = 0x36fca8 mem4.point = 0xa41f8
mem5.address = 0x36fc9c mem5.point = 0xa4288
sizeof(int *) = 4
free mem2 and mem4.
malloc 120byte for mem6.
mem6.address = 0x36fc90 mem6.point = 0xa4318
malloc 100 byte for mem2 and mem4 again.
mem2.address = 0x36fcc0 mem2.point = 0xa41f8
mem4.address = 0x36fca8 mem4.point = 0xa40d8
请按任意键继续. . .
由以上结果可以看出,内存申请时还是会使用之前的内存碎片的,只是会用不完造成较小的内存碎片。
*以上程序在Intel I5处理器,Win7系统,使用VS2010编译而成。