C ++数组分配并没有真正分配

时间:2016-05-10 20:53:13

标签: c++ memory memory-management allocation

我已经创建了Virtual Ram类来在运行时提升内存分配。

class VRam
{
  unsigned char ***data;
...
public:
  VRam(ulli length);
  void *allocate(ulli size);
  ...
}

在我的程序中,小数组或变量在组内存中分配,这允许我在开始时分配一个巨大的数组,稍后再使用它的某些部分然后清除整个事物。 问题如下: 我最近更新了它,通过将它们分成更小的块来支持大型数组。我的程序在此更新后工作得很好,但即使我将内存限制设置为2 GiB(此开始时分配的空间量),系统监视器显示它仅使用50 MiB,这很奇怪。经过一些测试:

ulli size = 2073741824;
    int blocknum = size / VBLOCK_SIZE;
    VRam *vr = new VRam(size);
    int **arrs = new int*[blocknum];
    for (int i = 0; i < blocknum; ++i) {
        //cout<<i<<endl;
        arrs[i] = (int*)vr->allocate(VBLOCK_SIZE);
        arrs[i][0] = i;     //<<<<<---------------
        for (int j = 0; j < VBLOCK_SIZE / 4; ++j) {
            //cout<<" "<<j<<endl;
            arrs[i][j] = j+i;    //<<<<-------------
        }
    }

我得到了以下结果: 如果我在分配的内存上构造所有内容,它将真正被分配,(第二个&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt; ----)并且它使用指定的空间量如果我不使用不构造所有东西(没有或前几个字节:第一个&lt;&lt;&lt; ---),那么将不使用内存。我可以在我的笔记本电脑上使用8 GiG Ram指定16个GiB,它仍在工作。 我的问题是,因为它似乎是某种内存优化,但我创建这个类的原因是使用内存来提升CPU。 这会导致速度有任何问题吗?如果是这样的话,如何在不写入内存中的每个字节的情况下绕过它? 我正在使用qmake编译Ubuntu 16.04 LTS(Qt 5.5.1 GCC 5.2.1 20151129,64位)。

3 个答案:

答案 0 :(得分:1)

这是因为Linux内存分配器的性质:它使您的进程认为它可以访问所需的内存量。但是,当您的进程实际触及它时(即通过读/写),内存是真正分配的。

引用malloc(3)

  

默认情况下,Linux遵循乐观的内存分配策略。这意味着当malloc()返回非NULL时,无法保证内存确实可用。

答案 1 :(得分:1)

您可能对this document感兴趣,其中详细介绍了Linux如何处理内存过量使用。

TL; DR是Linux将允许进程分配大量内存,但实际上只有在写入时才使用它。

答案 2 :(得分:1)

您需要了解虚拟内存和物理内存之间的区别。物理内存是机器中的实际RAM,它相当快(但比缓存或寄存器访问慢得多)。您要分配的是虚拟内存:在过去的30年或40年中,几乎每个严肃的操作系统都能够分配比物理内存更多的虚拟内存。

当你触摸一些虚拟内存时,它将被带入物理内存(通过从交换文件中复制它,或者,如果这是第一次通过将相应的物理内存归零来触摸虚拟内存)。当您的物理内存不足时,虚拟内存将被复制到交换文件中。

如果需要将虚拟内存复制到交换文件或从交换文件复制虚拟内存,这将非常慢。你想避免这么做太多。