【问题标题】:C++ array allocation doesn't really allocateC++ 数组分配并没有真正分配
【发布时间】:2016-05-10 20:53:12
【问题描述】:

我创建了 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;    //<<<<-------------
        }
    }

我得到了以下结果: 如果我在分配的内存上构建所有内容,它将真正被分配,(第二个

【问题讨论】:

标签: c++ memory memory-management allocation


【解决方案1】:

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

引用malloc(3):

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

【讨论】:

  • 是因为Linux内核分配的bug吧。
  • @SergeyA 这不是错误!它本来就是这样的,而且效果很好。
【解决方案2】:

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

TL;DR 是 Linux 将允许进程分配大量内存,但只有在写入时才会真正消耗它。

【讨论】:

    【解决方案3】:

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-05-09
      • 2013-08-16
      • 1970-01-01
      • 2013-01-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多