为什么我的程序设计用尽RAM和CPU使用所有RAM和CPU?

时间:2012-06-14 12:52:55

标签: c++ windows

#include <iostream>
#include <cassert>
#include <vector>
#include <ctime>
#include <cstdlib>
#include <Windows.h>

using namespace std;

char randomLetter()
{
    srand(time(0));
    char rValue;

    while(1)
    if((rValue=(rand()/129)) > 31) 
        return rValue;
}


int main()
{       
    vector<char> meegaString;

    for(int i=0; i < 10000000000; i++)
    {   
        meegaString.push_back(randomLetter());

                if(!(i%10000000)) 
            cout<<"There are: " <<i+1<<" chars in the list"<<endl;

    }

    system("pause");
    return 0;
}

运行此程序之前的RAM使用率约为2500/8000 MB。 当涉及3200时,抛出以下异常:

  

资源gormandizer.exe中0x773c15de处的未处理异常:   Microsoft C ++异常:内存位置的std :: bad_alloc   0x0045f864 ..

1)为什么这个程序没有填满整个可用内存,虽然它在64位操作系统上工作?

2)为什么只有26%的处理器(intel core i5)在使用中?

3 个答案:

答案 0 :(得分:4)

  1. 如上所述,向量的元素是连续存储的。此外,根据您在std::vector实现中使用的内存分配算法,它可能会尝试提前预先分配内存;分配比用于减少malloc / new次呼叫数量的内存更多的内存。因此,它可能会达到要求更多内存而不是32位操作系统可以支持的程度(这可以解释为什么64位进程可以工作,但是32位进程不会,尽管有足够的内存可用)。

  2. 您的进程在4个核心中运行,并且非常繁忙,因此它占用了大约25%的CPU时间。其他过程将构成其余的过程。

  3. 另请参阅:Being Smart About Vector Memory Allocation

答案 1 :(得分:2)

anthony-arnold的回答并不正确,如果我们用他的措辞取得一些自由,但仍有一些东西缺失。

正如其他人所提到的,如果您的Core i5是四核(都是i5的四核?),那么25%可能会建议可能其中一个核心(即您的流程所在的核心)接近100%忙,其他人大多闲着。与anthony-arnold的回答相反,25%没有表明其他进程占据了其他75%,它说其他75%的可用CPU时间都是浪费(空闲)。同样,如果您的CPU是四核,没有多线程测试应用程序,那么您的测试应用程序将无法消耗超过25%的整体。

如果你正在寻找内存空间耗尽,折扣内存分配碎片和其他开销,你就找到了它。正如其他人所说,您的应用似乎已构建为32位应用。即使在64位操作系统上运行,您的应用程序也永远无法满足超过32位地址空间可容纳的限制,即4Gb。即便如此,还有很多其他开销,包括为操作系统保留的虚拟地址空间,程序和共享库空间,堆栈空间以及分配给其他事物的堆空间以及堆空间开销。因此,你的meegaString矢量永远不会接近完整的4Gb,可能甚至不接近2Gb(如果构建为一个大地址空间感知的应用程序,可能会有点超过2Gb)。

现在关于anthony-arnold提到的“前向分配”点:所有STL容器都对摊销的运营时间作出承诺。 std :: vector类承诺,平均(即摊销),push_back()操作将是恒定时间(即O(1)),这意味着当其内容变得更大&amp;更大,做push_back()不会花费更长的时间。更长的时间(如果确实如此,它将是O(n))。偶尔执行push_back()需要比O(1)多得多,因为偶尔push_back()会导致容器的数据超过其当前分配的空间,并且需要执行重新分配并将其当前内容移动到新位置,并删除其旧内容。通过操作系统的合作,一个良好实现的自定义编写的STL实现可以做得更好,通过使用虚拟内存和MMU的技巧,使它不必实际移动内容,它只是告诉操作系统告诉MMU使数据的虚拟内存页面映射到新位置,但这完全是另一个问题,无论如何你都不需要担心它,因为它会在幕后发生。在任何情况下,是的,std :: vector类必须“预先分配”一个更大的内存块,而不是任何时候进行新的分配,因为这是它可以承诺O(1)push_back()时间的唯一方法。如果每次执行push_back()时都必须将内容移动到新分配的缓冲区,那么push_back()的时间复杂度将为O(n),而不是O(1),因为执行push_back的时间()会变得更长&amp;矢量数据越大,越长。

答案 2 :(得分:0)

vector类模板实现了一个动态数组,它需要一个连续的内存块。

关闭主题 - 为此,可以使用list容器,但stack似乎是最佳解决方案。但是,无论是列表还是堆栈,它仍然会崩溃并出现相同的错误(现在附近有4600 MB)。看起来很相似,但现在不是选择了无效数据结构的错误。这是因为32位应用程序具有非常可用的内存,因此为了完全填充它,请在x64平台上编译此程序。

#include <iostream>
#include <stack>
#include <ctime>
#include <cstdlib>


using namespace std;

char randomLetter()
{
    srand(time(0));
    char rValue;

    while(1)
    if((rValue=(rand()/129)) > 31) 
        return rValue;
}


int main()
{       
    stack<char> meegaString;

    for(int i=0; i < 10000000000; i++)
    {   
        meegaString.push(randomLetter());

                if(!(i%10000000)) 
            cout<<"There are: " <<i+1<<" chars in the list"<<endl;

    }




    system("pause");
    return 0;
}