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