malloc()与new[]的内存开销

memory overhead of malloc() vs new[]

本文关键字:内存 开销 new malloc      更新时间:2023-10-16

我想保留一块内存(1GB),以便将数据加载到其中进行分析。每条记录大约10K字节,至少有100k条记录。最初我打算在c++代码中使用malloc,但有人建议我不要这样做。

现在,使用char * block = new char[1000000000]是否需要额外的内存来存储指向数组中1,000,000,000个元素的指针?使用char * block = malloc(1000000000 * sizeof(char))需要比new[]更少的额外内存来创建吗?

我的目标是使用尽可能少的内存,并且不希望在内存中出现大量记录。

谢谢:)

在我的Linux机器上:

<标题> Malloc h1>
$ make malloc
$ valgrind ./malloc 2>&1|grep total
==23855==   total heap usage: 1 allocs, 0 frees, 1,000,000,000 bytes allocated
<标题>新
//new.cc
int main() { char* block = new char[1000000000]; }
运行时:

$ make new
$ valgrind ./new 2>&1|grep total
  ==24460==   total heap usage: 2 allocs, 0 frees, 1,000,072,704 bytes allocated

对于不同的值,72,704B开销保持不变。

为了使operator delete[]能够正确地与非pod一起工作,数组的大小(单个size_t)通常放在整个块的开头,并且第一个对象位于第一个适当对齐的地址。

对于pod, operator new[](没有初始化式)通常与malloc相同。

对于初始化式(同样是POD类型),结果取决于编译器:它可以转换为遍历元素的循环,也可以简化为memset

考虑到你打算分配的大量内存,malloc的结果取决于运行时-一些实现对块大小有硬性上限。

如果你的目标是Windows,你可以使用VirtualAlloc这个大小的东西。同样,在*nix上使用mmap

你问:

现在,使用char * block = new char[1000000000]是否需要额外的内存来存储指向数组中1,000,000,000个元素的指针?

绝对不会。

来自c++ 11标准(第5.3.4节新)

如果分配的对象是一个数组(也就是说,使用noptr-new-declarator语法,或者new-type-idtype-id表示数组类型),new-表达式产生指向数组初始元素(如果有)的指针。
这里的关键部分是,返回给一个指向数组 初始元素(如果有的话)的指针。

你还问:

使用char * block = malloc(1000000000 * sizeof(char))是否需要比new[]更少的额外内存?

标准没有指定任何与使用任何分配方法相关的开销。在大多数实现中,与这两个方法相关的内存开销即使不完全相同,也应该大致相同。

new[N]保留的比要求的多一点。它在开始处存储计数器[N](以知道使用delete[]需要调用多少析构函数),并在它后面返回一个内存块。

如果您使用new来分配字符数组,您将得到一个字符数组。每个元素都不会有额外的指针。你只会得到一个大的连续内存区域,类似于malloc()

new将做的是分配内存,然后调用构造函数,在你的情况下不会做任何后果,因为这只是一个普通旧数据数组。

我使用Visual Studio 2013与调试编译运行一个快速检查,并查看Windows任务管理器中的内存分配,因为我先跳过new,然后malloc()和每一步的内存分配数字看起来差不多。

对于如此大的内存区域,您可能会遇到页面错误,因为操作系统在访问内存区域的各个部分时将您的大内存区域调入和调出。我不确定你真的能做些什么,我也不确定这是一个大问题。在一定程度上,任何交换行为将取决于您拥有的物理内存量,以及额外服务和应用程序的混合以及它们的内存使用情况。