首页 > 解决方案 > 巨大的内存分配:堆栈与堆

问题描述

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

标签: c++memoryheap-memorystack-memory

解决方案


是的,建议动态地进行大量分配——因为这样你就可以优雅地应对失败(关于术语的强制性说明)。

例如,这个:

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

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

反过来

void will_just_die() {
  int a[SomeEnormousConstant];
  // ...
}

a如果无法真正创建,则没有恢复机制。该程序只会崩溃,很难,没有堆栈展开或(标准)错误处理机制。

可能会立即发生,或者它可能仅在您实际尝试访问a超过可以成功分配的内容时发生。如果你很不走运,它甚至可能看起来有效,但会破坏其他东西。


给定分配如何在外部显示的细节非常依赖于操作系统,我不确定您使用的是什么 - 应用程序管理器是 OSX 吗?

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

如果自动(“堆栈”)分配只是执行帧指针运算并再次依赖于物理页面的延迟分配,则这不会影响虚拟或物理大小(同样,直到您尝试实际访问该内存)。

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


推荐阅读