c++ - 巨大的内存分配:堆栈与堆
问题描述
我制作了一个需要 1 GB 内存的结构。当我在堆上分配它时,程序启动很快,我在应用程序管理器中看到它的内存使用量达到了这个数量,但是当我像一个简单的变量一样在堆栈上分配它时,应用程序需要更多的时间来启动和在应用程序管理器中,我看到它没有使用那么多内存(只有几 KB)。为什么?这是否意味着建议在堆中存储大量数据?这种情况会更快吗?我知道由于映射等原因,通常在堆栈上分配内存会更快,但在这种情况下,这很奇怪。谁能给我解释一下?提前致谢!
解决方案
是的,建议动态地进行大量分配——因为这样你就可以优雅地应对失败(关于术语的强制性说明)。
例如,这个:
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,以及您的操作系统/平台详细信息才能得到答案。
推荐阅读
- github - github上关于cypress拖放的问题
- android - Jetpack Compose 如何在 BasicTextField 中居中提示和输入
- c++ - IMF MediaSession Video Seek 未执行到指定位置
- r - 在 R 的每一列中查找并保留重复项
- influxdb - 涌入数据库。中断查询的条件
- encryption - 解析 EC 公钥
- javascript - 如何在 Javascript 条形图中传递 JSON 数据?
- javascript - 如何使用 laravel 和 jquery 在数据表中添加行跨度
- amazon-web-services - 我是否可以在不拥有域的情况下在 AWS 提供的 ALB 子域上设置 SSL?
- google-sheets - 从一个单元格中查找多个值