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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了巨大的内存分配:堆栈与堆相关的知识,希望对你有一定的参考价值。

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

答案

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

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

这是否意味着建议在堆中记录大量数据?

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

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

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

另一答案

是的,建议动态地进行大量分配 - 因为那时你可以优雅地应对失败(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而不是成功分配时才会发生。如果你非常不走运,它甚至可能会起作用,但会破坏别的东西。


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

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

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

我不知道为什么启动自动版需要更长的时间 - 你必须提供一个MCVE,这实际上是可重现的,以及你的操作系统/平台细节,以获得答案。

以上是关于巨大的内存分配:堆栈与堆的主要内容,如果未能解决你的问题,请参考以下文章

堆栈与堆栈和堆与堆

C++ 堆栈与堆分配

栈与堆的区别

栈与堆

从Java的堆栈到Equals和==的比較

C 内存的动态分配怎么用?有啥建议吗?内存分配中栈与堆到底有啥不同啊?