c – 有意地浪费所有的主要记忆来学习分裂

前端之家收集整理的这篇文章主要介绍了c – 有意地浪费所有的主要记忆来学习分裂前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
在我的班上,我们有一个任务,其中一个问题是:

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秒.对我来说,第二个序列应该花费更长的时间来显示碎片是如何工作的,但是由于使用了交换,所以不会发生.有没有办法解决这个问题,或者我假设错了?

我会问教授,我在星期一,但直到那时,任何帮助将不胜感激.

解决方法

许多libc实现(我认为包含glibc)在调用free()时不释放内存到操作系统,但保留它,以便您可以在没有系统调用的下一个分配上使用它.此外,由于现代分页和虚拟内存分层的复杂性,您无法确定物理内存中的任何位置,因此有意将其分段(即使分散)也几乎无法实现.你必须记住,所有的虚拟内存,所有的物理内存都是不同的野兽.

(以下是为Linux编写,但可能适用于Windows和OSX)

当您的程序进行第一次分配时,假设操作系统有足够的物理内存来挤压所有的页面.它们并不全部在物理内存中的每个页面旁边 – 它们分散在任何地方.然后,操作系统会修改页表以创建一组连续的虚拟地址,这些地址指的是内存中的分散页面.但是这是事情 – 因为你并没有真正使用你分配的第一个内存,所以它成为一个很好的替代选择.所以,当你来做下一个分配时,那些内存不足的操作系统,可能会换掉一些页面,为新的空间腾出空间.因此,您实际上是测量磁盘速度,以及操作系统分页机制的效率 – 而不是碎片化.

记住,一连串的虚拟地址在实践中(甚至在内存中)几乎从来没有物理上连续.

原文链接:https://www.f2er.com/c/115045.html

猜你在找的C&C++相关文章