c – 有意地浪费所有的主要记忆来学习分裂
在我的班上,我们有一个任务,其中一个问题是:
我的执行情况如下: #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 Onen"); 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 Twon"); for(int i=0;i<(3*m);i+=2) { free(container[i]); } begin2 = clock(); printf("Step Threen"); 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: %.5fn",tdif); printf("To Allocate the second array it took: %.5fn",tdif2); system("pause"); }; 我已经改变了这几种不同的方式,但我看到的一致性是,当我最初分配3 * m * 500000元素数组的内存,它占用了所有可用的主内存.但是当我告诉它释放它们时,内存不会释放到操作系统,所以当它分配m * 700000元素数组时,它会在页面文件(swap memory)中执行,因此它不会实际显示内存碎片. 上面的代码运行了1000次,平均值,需要相当长的一段时间.第一个序列平均值为2.06913秒,第二个序列为0.67594秒.对我来说,第二个序列应该花费更长的时间来显示碎片是如何工作的,但是由于使用了交换,所以不会发生.有没有办法解决这个问题,或者我假设错了? 我会问教授,我在星期一,但直到那时,任何帮助将不胜感激. 解决方法
许多libc实现(我认为包含glibc)在调用free()时不释放内存到操作系统,但保留它,以便您可以在没有系统调用的下一个分配上使用它.此外,由于现代分页和虚拟内存分层的复杂性,您无法确定物理内存中的任何位置,因此有意将其分段(即使分散)也几乎无法实现.你必须记住,所有的虚拟内存,所有的物理内存都是不同的野兽.
(以下是为Linux编写,但可能适用于Windows和OSX) 当您的程序进行第一次分配时,假设操作系统有足够的物理内存来挤压所有的页面.它们并不全部在物理内存中的每个页面旁边 – 它们分散在任何地方.然后,操作系统会修改页表以创建一组连续的虚拟地址,这些地址指的是内存中的分散页面.但是这是事情 – 因为你并没有真正使用你分配的第一个内存,所以它成为一个很好的替代选择.所以,当你来做下一个分配时,那些内存不足的操作系统,可能会换掉一些页面,为新的空间腾出空间.因此,您实际上是测量磁盘速度,以及操作系统分页机制的效率 – 而不是碎片化. 记住,一连串的虚拟地址在实践中(甚至在内存中)几乎从来没有物理上连续. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |