巨大的内存分配:堆栈与堆
Huge memory allocation: stack vs heap
>我做了一个需要1 GB内存的结构。当我在堆上分配它时,程序启动得很快,我在应用程序管理器中看到,它的内存使用量上升到那个数量,但是当我像一个简单的变量一样在堆栈上分配它时,应用程序需要更多时间来启动,在应用程序管理器上,我看到它没有使用那么多的内存(只有几千KB(。这是为什么呢?这是否意味着建议在堆中存储大量数据?这种情况更快吗?我知道通常由于映射等原因,在堆栈上分配内存会更快,但在这种情况下,这很奇怪。谁能解释一下? 提前感谢!
在典型的桌面系统上,堆栈的大小通常约为一到几兆字节。在嵌入式设备上可能更少。
如果分配的内存超过堆栈大小的内存,则操作系统通常会在您尝试访问内存时立即终止程序。
这是否意味着建议在堆中记录大量数据?
建议对大量数据使用免费存储(动态分配(,因为大量数据会溢出堆栈。
我看到应用程序管理器没有使用那么多的内存(只有几KB(。
通常,操作系统在访问进程时为该内存分配一页内存。由于您的程序没有因堆栈溢出而崩溃,我怀疑您从未访问过内存,因此没有为数据分配内存。
是的,建议动态进行大量分配 - 因为这样您就可以优雅地应对失败(术语的强制性说明(。
例如,这个:
void might_throw(size_t sz) {
std::vector<int> v(sz);
// ...
}
如果对于足够大的sz
失败,将抛出std::bad_alloc
,这意味着我可以选择捕获异常并使用较小的数字重试。即使我无法有效地恢复,堆栈展开也可以安全地清理我的其他对象。
相反
void will_just_die() {
int a[SomeEnormousConstant];
// ...
}
如果无法真正创建a
则没有恢复机制。该程序只会崩溃,很难,没有堆栈展开或(标准(错误处理机制。
这可能会立即发生,也可能仅在您实际尝试访问比成功分配的更多的a
时才会发生。如果你很不幸,它甚至可能看起来有效,但会破坏其他东西。
给定分配如何在外部显示的详细信息非常依赖于操作系统,我不确定您正在使用什么 - 应用程序管理器是OSX管理器吗?
直接映射大型动态分配是很常见的,在这种情况下,它会立即显示为虚拟大小的增加,但除了访问之外,可能仍然不会分配任何物理页面。
如果自动("堆栈"(分配只是执行帧指针算术,并再次依赖于物理页面的延迟分配,这不会影响虚拟或物理大小(同样,直到您尝试实际访问该内存(。
我不知道为什么自动版本需要更长的时间才能启动 - 您必须提供一个实际上可重现的 MCVE,以及您的操作系统/平台详细信息才能获得答案。
- 从堆栈分配的原始指针构造智能指针
- 在什么情况下,两个堆栈分配的结构对象的 this 点指向同一个地址?
- 如何模板化堆栈分配的多态指针数组到接口,包括派生类型的相应点?
- 堆栈分配的类类型.为什么两个 ID 实例的地址相同?
- C++析构函数调用两次,堆栈分配的复合对象
- 了解通过引用传递取消引用指针时C++堆/堆栈分配
- C++,在对象内分配多个数据时,堆栈分配是否更有效? 在下面的程序中,类A_Heap的效率会更低吗?
- 何时在函数中声明堆栈分配变量?
- 使用 std::map 的递归堆栈分配如何工作?
- tcmalloc 与纯堆栈分配性能有多接近
- 安全分配堆栈分配的阵列
- C++ 中的黑白堆分配对象和堆栈分配对象的性能差异
- 跟踪(堆栈分配)对象
- 堆栈分配的确切时间
- 未初始化的值是由堆栈分配 - Qt - C++创建的
- 用于堆栈分配对象的C++虚拟析构函数内联
- C STD :: BAD_ALLOC来自堆栈分配
- 是使用COM创建的对象,将采用分配或堆栈分配的内存
- C++ 中针对大型的堆栈分配
- 堆栈分配的向量如何在 C++ 中扩展