Memory fragmentation in C: Design,implement,and run a C-program that does the following: it allocated memory for a sequence of of 3m arrays of size 500000 elements each; then it deallocates all even-numbered arrays and allocates a sequence of m arrays of size 700000 elements each. Measure the amounts of time your program requires for the allocations of the first sequence and for the second sequence. Choose m so that you exhaust all of the main memory available to your program. Explain your timings
我的执行情况如下:
#include <iostream> #include <time.h> #include <algorithm> void main(){ clock_t begin1,stop1,begin2,stop2; double tdif = 0,tdif2 = 0; for(int k=0;k<1000;k++){ double dif,dif2; const int m = 50000; begin1 = clock(); printf("Step One\n"); int *container[3*m]; for(int i=0;i<(3*m);i++) { int *tmpAry = (int *)malloc(500000*sizeof(int)); container[i] = tmpAry; } stop1 = clock(); printf("Step Two\n"); for(int i=0;i<(3*m);i+=2) { free(container[i]); } begin2 = clock(); printf("Step Three\n"); int *container2[m]; for(int i=0;i<m;i++) { int *tmpAry = (int *)malloc(700000*sizeof(int)); container2[i] = tmpAry; } stop2 = clock(); dif = (stop1 - begin1)/1000.00; dif2 = (stop2 - begin2)/1000.00; tdif+=dif; tdif/=2; tdif2+=dif2; tdif2/=2; } printf("To Allocate the first array it took: %.5f\n",tdif); printf("To Allocate the second array it took: %.5f\n",tdif2); system("pause"); };
我已经改变了这几种不同的方式,但我看到的一致性是,当我最初分配3 * m * 500000元素数组的内存,它占用了所有可用的主内存.但是当我告诉它释放它们时,内存不会释放到操作系统,所以当它分配m * 700000元素数组时,它会在页面文件(swap memory)中执行,因此它不会实际显示内存碎片.
上面的代码运行了1000次,平均值,需要相当长的一段时间.第一个序列平均值为2.06913秒,第二个序列为0.67594秒.对我来说,第二个序列应该花费更长的时间来显示碎片是如何工作的,但是由于使用了交换,所以不会发生.有没有办法解决这个问题,或者我假设错了?
我会问教授,我在星期一,但直到那时,任何帮助将不胜感激.
解决方法
(以下是为Linux编写,但可能适用于Windows和OSX)
当您的程序进行第一次分配时,假设操作系统有足够的物理内存来挤压所有的页面.它们并不全部在物理内存中的每个页面旁边 – 它们分散在任何地方.然后,操作系统会修改页表以创建一组连续的虚拟地址,这些地址指的是内存中的分散页面.但是这是事情 – 因为你并没有真正使用你分配的第一个内存,所以它成为一个很好的替代选择.所以,当你来做下一个分配时,那些内存不足的操作系统,可能会换掉一些页面,为新的空间腾出空间.因此,您实际上是测量磁盘速度,以及操作系统分页机制的效率 – 而不是碎片化.
记住,一连串的虚拟地址在实践中(甚至在内存中)几乎从来没有物理上连续.