int main(int argc, const char* argv[])
{
for(unsigned int i = 0; i < 10000000; i++)
char *c = new char;
cin.get();
}
在上面的代码中,为什么我的程序会使用471MB内存而不是10MB内存?
答案 0 :(得分:4)
RAM的分配来自运行时库和操作系统的共同努力。为了识别示例代码请求的一个字节,有一些结构可以向运行时标识这个内存。它有时是双链表,但它由操作系统和运行时实现定义。
您可以通过这种方式进行类比:如果您有一个链接列表容器,那么您感兴趣的只是您在每个链接中放置的内容,但容器必须指向其他链接容器以维护链表。
如果您使用调试器或其他调试工具来跟踪内存,这些结构可能会更大,从而使每次分配成本更高。
RAM通常不会从数组中分配,但可以重载新运算符以更改分配行为。它可能是从一个数组(在你的例子中是一个大的)中专门分配的,这样分配的行为就像你期望的那样,在某些应用程序中,这是控制内存和提高性能的特定策略(尽管细节通常更多)复杂而不是简单的插图)。
答案 1 :(得分:3)
分配不仅包含已分配的内存本身,而且至少有一个单词告诉delete
它必须释放多少内存;此外,这是一个必须正确对齐的数字,因此在分配的char之后会有一定的填充,以确保下一个块正确对齐。在64位机器上,这意味着每个分配至少16个字节(8个字节用于保存大小,1个字节用于保存字符,7个字节用于确保正确对齐)。
然而,很可能不是唯一存储的数据;为了帮助内存分配器找到空闲内存,可能存储额外的数据;如果假设数据由三个指针组成,则每个分配一个总共40个字节,这与您的数据非常匹配。
另请注意,分配器还将从操作系统请求比实际分配所需的更多内存,因此不需要为每个小分配执行昂贵的OS调用。也就是说,运行时库从操作系统中分配更大的内存块,然后为程序的分配削减较小的内存块。因此,通常会有一些从操作系统分配的内存(因此显示在任务管理器中),但尚未分配给程序中的某个对象。