如何解释内存分配延迟的剧烈跳跃?

时间:2013-11-29 01:53:02

标签: c++ c windows memory windows-ce

英特尔赛扬847,内存为8GB。 (C / C ++而不是.NET)

这是Windows EC7上唯一运行的线程/函数。

它只是循环分配1MB内存,1000次。

然而,在大约第122次迭代循环之后,将跳转从大约47微秒分配到327微秒。

有什么可能的原因可以向我的老板解释这一点?

while ( i < ITERATIONS )
{
QueryPerformanceCounter(&li);
start = double(li.QuadPart) / PCFreq;

// allocate 1MB
ptr = new char [1048576]; // 1 byte * 1048576 = 1 MB

QueryPerformanceCounter(&li);
stop = double(li.QuadPart) / PCFreq;

delayAlloc[i] = stop - start;

}

enter image description here

编辑

为了确定,我再次执行了3次测试,每个结果与此非常相似:

enter image description here

3 个答案:

答案 0 :(得分:4)

让我们简化你的代码并删除时间。

while ( i < ITERATIONS )
{
    // allocate 1MB
    ptr = new char [1048576]; // 1 byte * 1048576 = 1 MB
}

系统正在为您分配1Mb并返回您的地址。然后你要求另一个,并将新地址存储在你持有前一个地址的同一个变量中。

new返回一个指针,指针实际上只是分配的地址。它不是一个特殊的电子密钥,不是具有范围的对象,它只是内存中分配开始的位置的数值。

当您不再需要内存时,告诉分配器是您的责任。无论您是否存储地址数据,都无法知道您对该地址数据的处理方式。

while ( i < ITERATIONS )
{
    // allocate 1MB
    ptr = new char [1048576]; // 1 byte * 1048576 = 1 MB

    delete [] ptr;
}

如果您不这样做,分配的内存将从不返回到池,直到您的应用程序终止。

这意味着您的应用程序的内存占用量正在增长。在正常的Windows下,这可能不是问题但是你在Windows的嵌入式风格下运行,其中一个 Mb的内存已经是一个重要的数量。第一个122Mb可能预先保留给您的应用程序。但是一旦你分配了应用程序开始的所有堆,分配器就必须调整它的堆大小才能为你提供额外的分配,而且由于这是嵌入式Windows,所以调整大小是悲观的。

答案 1 :(得分:3)

我能想到的一个可能原因是程序堆在某个阶段被完全占用,此后内存管理器必须通过循环和跳转来管理进一步的分配请求,方法是将一些已经分配的块交换到二级存储。很大程度上取决于您安装的内存量以及可用于程序的内存量。

如果将分配大小设置为512K而不是1MB,会出现什么行为?是否会发生同样的事情,但是在第200次迭代时?你可以增加可用内存并试试吗? (我不知道Windows EC7是什么,但我的响应基于我的WinDesktop体验)。

答案 2 :(得分:2)

您的代码根本不使用RAM,直到您实际访问阵列才会发生这种情况。因此,唯一需要做的工作就是在虚拟内存地址空间中找到一个漏洞并提交它。找到一个洞就不会像这样突然跳起来。承诺可以,有一个便宜和昂贵的版本。便宜的是分页文件中的空间已经可用的地方。昂贵的是需要通过增长分页文件来创建它。

通过运行程序两次来验证这一点。第二次跳跃应该发生或者根本不发生。