我有一个动态分配的大型数组(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中关闭交换,但这样才能解决问题。
答案 0 :(得分:2)
我认为内存分配器在调试模式下进行了一些链接,以便更好地检测内存处理错误。它将访问每个已分配的块以在每个块中写入几个字节,从而迫使系统提交快速分配的所有页面。
在发布模式下,您的代码执行块的线性填充,从而一次提交一页。
至于限制内存量,您可以通过系统调用来了解可用资源。 These, for instance, in Windows environment
如果需要内存锯,则系统调用失败是没有意义的,因为可用内存量由于给定程序无法控制的情况而不断变化(就像其他应用程序正在启动一样)。
有可能使一些内存块不可交换(即锁定在RAM中),但这种用法通常仅限于驱动程序等系统层。
您可以检测可用内存并强制执行分配限制。
请注意,这是一场危险的比赛;因为你通常不会独自在计算机上运行,并且无法确定以后是否会启动另一个应用程序并消耗更多内存。
如果交换是您的应用程序的杀手,您应该考虑采用安全边距(即尝试为系统留下500Mb或1 Gb的RAM)