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

Huge memory allocation: stack vs heap

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

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

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

Does it mean it's recommended to story big amount of data in the heap?

大数据建议使用free store(动态分配),大数据会溢出栈。

Application Manager i saw it is not using that amount of memory (just few KBs).

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

是的,建议动态进行大量分配 - 因为这样您就可以优雅地应对失败 (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 时发生。如果您非常不幸,它甚至可能 看起来 可以工作,但会破坏其他东西。


给定分配如何在外部显示的详细信息非常 OS 相关,我不确定您使用的是什么 - Application Manager 是 OSX 吗?

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

如果自动 ("stack") 分配只是执行帧指针算法并再次依赖物理页面的惰性分配,这不会影响虚拟或物理大小(同样,直到您尝试实际上正在访问该内存)。

我不知道为什么自动版本需要更长的时间才能启动 - 你必须提供一个 MCVE 实际上可以重现的,以及你的 OS/platform 详细信息得到答案。