这是我在Windows 7下对MSVC ++ 2010进行的简单测试:
// A struct with sizeof(s) == 4, e.g 4 bytes
struct s
{
int x;
};
// Allocate 1 million structs
s* test1 = new s[1000000];
// Memory usage show that the increase in memory is roughly 4 bytes * 1000000 - As expected
// NOW! If I run this:
for (int i = 0; i < 1000000; i++)
new s();
// The memory usage is disproportionately large. When divided by 1000000, indicates 64 bytes per s!!!
这是常识还是我错过了什么?之前我总是习惯在需要时动态创建对象。例如,网格中每个三角形的新三角形()
单个实例的动态内存分配确实存在数量级的开销吗?
干杯
编辑:
使用g ++在Windows XP上编译并运行相同的程序: 现在开销是16字节,而不是之前观察到的64字节!非常有趣。
答案 0 :(得分:3)
不一定,但操作系统通常会代表您以任何方便的大小块保留内存;在你的系统上,我猜它会给你每个请求64个字节的倍数。
毕竟,跟踪内存分配有相关的开销,并且保留非常少的金额是不值得的。
答案 1 :(得分:1)
是否为调试版本?因为在调试版本中,msvc会在对象周围分配“警卫”,以查看是否覆盖了对象边界。
答案 2 :(得分:1)
任何单个内存分配通常都会产生开销。现在这是我对malloc
而不是new
的了解,但我怀疑它是一样的。
存储器领域的一部分,当被分割出来(例如)30个字节时,通常会有一个标题(例如,16个字节,所有这些数字只是下面的例子,它们可能不同)和可以填充为16个字节的倍数,以便于竞技场管理。
标题通常很重要,允许在完成部分后将该部分重新集成到空闲内存池中。
它包含有关块大小的信息,并且可能还有内存保护(用于检测竞技场的损坏)。
因此,当你分配一百万个结构数组时,你会发现它为标题使用了额外的16个字节(四百万和十六个字节)。当您尝试分配一百万个单独的结构时,每个中的每一个将具有该开销。
我更详细地回答了相关问题here。我怀疑C ++会有更多所需的标题信息,因为它可能必须存储超出节大小的项目数(对于正确的析构函数调用),但这只是我的假设。它不会影响每个分配项目需要某种会计信息的事实。
如果您真的想查看空间的用途,您需要深入了解MSVC运行时源代码。
答案 3 :(得分:1)
您应该检查malloc
实施。可能这会让事情变得清晰。
不确定是否可以在某处查看MSVC ++的malloc
。如果没有,看看其他一些实现,它们可能在某种程度上相似。
不要指望malloc
实现很容易。它需要在分配的虚拟页面中搜索一些可用空间或分配新的虚拟页面。它必须快速做到这一点。尽可能快地。它必须是多线程安全的。也许你的malloc
实现有某种bitvector,它可以保护某些页面中的64位块是空闲的,它只需要下一个空闲块。