#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)在使用中?
答案 0 :(得分:4)
如上所述,向量的元素是连续存储的。此外,根据您在std::vector
实现中使用的内存分配算法,它可能会尝试提前预先分配内存;分配比用于减少malloc
/ new
次呼叫数量的内存更多的内存。因此,它可能会达到要求更多内存而不是32位操作系统可以支持的程度(这可以解释为什么64位进程可以工作,但是32位进程不会,尽管有足够的内存可用)。
您的进程在4个核心中运行,并且非常繁忙,因此它占用了大约25%的CPU时间。其他过程将构成其余的过程。
答案 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;
}