gpt4 book ai didi

c++ - 动态内存分配在调试时似乎是即时的,但在 Release模式下是渐进的

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:10:27 25 4
gpt4 key购买 nike

我有一个很大的动态分配数组(C++,MSVC110),我是这样初始化它的:

try {
size_t arrayLength = 1 << 28;
data = new int[arrayLength];
for (size_t i = 0; i < arrayLength; ++i) {
data[i] = rand();
}
}
catch (std::bad_alloc&) { /* Report error. */ }

在我尝试分配超过系统实际 RAM(例如 10 GB)之前,一切都很好。我原以为会捕获到 bad_alloc 异常,但系统 (Win7) 开始疯狂切换等等。您知道我在说什么。

然后我检查了任务管理器中的情况,发现了一件有趣的事情,在 Debug模式下分配是即时的,但在 Release模式下,它是渐进的。

Debug模式:

Debug mode allocation graph

发布方式:

Release mode allocation graph

是什么原因造成的?这会对性能产生负面影响吗?我做错了什么吗?是操作系统造成的吗?还是 C++ 分配器?

如果没有足够的内存,我实际上更愿意得到一个异常,而不是进入无休止的交换循环。有什么办法可以用 C++ 实现吗?

我知道一种解决方案可能是在 Windows 中关闭交换,但这只能解决我的问题。

最佳答案

我认为内存分配器正在 Debug模式下进行一些链接,以便更好地检测内存处理错误。它将访问每个分配的 block 并在每个 block 中写入几个字节,从而迫使系统快速提交所有分配的页面。

在 Release模式下,是您的代码对 block 进行线性填充,因此一次提交一页。

至于限制内存量,您可以通过系统调用来了解可用资源。 These, for instance, in Windows environment .

如果需要内存 sawp,则系统调用失败是没有意义的,因为可用内存量会因给定程序无法控制的情况(如正在启动的其他应用程序)而不断变化。

有可能使一些内存块不可交换(即锁定在 RAM 中),但这种使用通常仅限于系统层,如驱动程序。

由您来检测可用内存并强制执行分配限制。

注意这是一个危险的游戏;因为您通常不会在计算机上单独运行,并且无法判断稍后是否会启动另一个应用程序并占用更多内存。

如果交换对您的应用程序来说是一个 killer ,您应该考虑考虑安全边际(即尝试为系统留出 500Mb 或 1Gb 的可用 RAM)

关于c++ - 动态内存分配在调试时似乎是即时的,但在 Release模式下是渐进的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21415241/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com