巨大的内存分配:堆栈与堆

时间:2018-09-11 14:48:31

标签: c++ memory stack heap

我制作了一个需要1 GB内存的结构。当我在堆上分配它时,程序启动很快,并且在“应用程序管理器”中看到,它的内存使用量已达到该数量,但是当我像一个简单变量一样将其分配在堆栈上时,应用程序需要更多的时间来启动和在应用程序管理器中,我看到它没有使用那么多的内存(只有几个KB)。为什么?这是否意味着建议在堆中存储大量数据?那样的情况更快吗?我知道通常由于映射等原因,在堆栈上分配内存的速度更快,但是在这种情况下,这很奇怪。谁能向我解释一下? 预先感谢!

2 个答案:

答案 0 :(得分:1)

在典型的台式机系统上,默认情况下,堆栈的大小通常约为1兆字节。在嵌入式设备上可能更少。

如果您分配的内存超出了堆栈的容量,则操作系统通常会在您尝试访问内存时立即终止程序。

  

这是否意味着建议对堆中的大量数据进行故事处理?

建议对大量数据使用免费存储(动态分配),因为大量数据将使堆栈溢出。

  

应用程序管理器我发现它没有使用那么多的内存(只有几个KB)。

通常,操作系统在访问该进程时会为其分配一个内存页。由于您的程序不会因堆栈溢出而崩溃,因此我怀疑您从未访问过内存,因此没有为数据分配内存。

答案 1 :(得分:1)

是的,建议动态地进行大量分配-因为这样您就可以轻松应对失败(obligatory note on terminology)。

例如,此:

void might_throw(size_t sz) {
  std::vector<int> v(sz);
  // ...
}
如果

在足够大的std::bad_alloc上失败,它将抛出sz,这意味着我可以选择捕获异常并以较小的数字重试。即使无法有效恢复,堆栈展开也可以安全地清除其他对象。

相反

void will_just_die() {
  int a[SomeEnormousConstant];
  // ...
}
如果无法真正创建a,则

没有恢复机制。该程序将崩溃,很难,没有堆栈展开或(标准)错误处理机制。

可能立即发生,或者仅当您实际尝试访问的a超出成功分配的数量时,才会发生。如果您很不幸,它甚至可能会出现可以工作,但会破坏其他功能。


给定分配如何在外部显示的详细信息取决于操作系统,我不确定您使用的是什么-Application Manager是OSX吗?

直接映射大型动态分配是很常见的,在这种情况下,虚拟分配会随着虚拟大小的增加而立即显示,但是除了访问外,可能仍不会分配任何物理页面。

如果自动(“堆栈”)分配只是执行帧指针算术,并且再次依赖于物理页的惰性分配,那么这将不会影响虚拟或物理大小(再次,直到您尝试实际访问该内存为止) )。

我不知道为什么自动版本需要花更长的时间才能开始-您必须提供一个MCVE,它实际上是可复制的,以及您的OS /平台详细信息才能得到答案