c – 动态内存分配在调试中似乎是即时的,但在发布模式下是渐进的

我有一个动态分配的大型数组(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)开始交换疯狂等等.你知道我在说什么.

然后我检查了我的任务管理器中的情况并注意到有趣的事情,在调试模式下,分配是即时的,但在发布时,它是渐进的.

调试模式:

发布模式:

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

如果没有足够的内存而不是无休止的交换循环,我实际上更愿意得到异常.有没有办法如何在C中实现它?

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

最佳答案 我认为内存分配器在调试模式下进行了一些链接,以便更好地检测内存处理错误.它将访问每个已分配的块以在每个块中写入几个字节,从而迫使系统提交快速分配的所有页面.

在发布模式下,您的代码执行块的线性填充,从而一次提交一个页面.

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

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

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

您可以检测可用内存并强制执行分配限制.

请注意,这是一个危险的游戏;因为你通常不会独自在计算机上运行,​​并且无法确定以后是否会启动另一个应用程序并消耗更多内存.

如果交换是您的应用程序的杀手,您应该考虑采取安全边际(即尝试为系统留下500Mb或1 Gb的RAM)

点赞