#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时,会引发以下exception:
资源gormandizer.exe中的0x773c15de未处理的exception:Microsoft C ++exception:内存位置0x0045f864处的std :: bad_alloc ..
1)为什么这个程序没有填充整个可用的内存,虽然它在64位操作系统上工作?
2)为什么只有26%的处理器(intel core i5)被使用?
如上所述,矢量的元素是连续存储的。 另外,根据实现std::vector
使用的内存分配算法,它可能试图提前预分配内存; 分配比用来减少malloc
/ new
调用次数更多的malloc
。 因此,它可能会达到要求更多的内存比32位操作系统可以支持(这可以解释为什么64位进程将工作,但32位进程不会,尽管有足够的内存可用)。
你的进程在4个核中运行,而且非常繁忙,因此它占用了大约25%的CPU时间。 其他进程将弥补其余的。
另请参阅: 智能关于向量内存分配
安东尼·阿诺德的答案并不是不正确的,如果我们对他的措词采取一些自由的话,但是还有一些东西是不存在的。
正如其他人所说,如果你的Core i5是一个四核(都是i5的四核?),那么25%可能表明,也许核心之一(即你的进程的核心)几乎100%忙碌,其他人大多闲置。 与安东尼 – 阿诺德的答案相反,25%并不表示其他进程正在占用另外75%,这就是说,另外75%的可用CPU时间只是浪费(闲置)。 同样,如果你的CPU是四核的,没有多线程的测试应用程序,你的测试应用程序将不能消耗超过整体的25%。
如果你正在寻找内存空间耗尽,折扣内存分配碎片和其他开销,你找到了它。 正如其他人所建议的,您的应用似乎已经被构建为32位应用。 即使在64位操作系统上运行,您的应用也永远无法解决的问题超出了32位地址空间的限制,即4Gb。 即使如此,还有很多其他开销,包括为操作系统保留的虚拟地址空间,程序和共享库空间,堆栈空间以及分配给其他事物的堆空间以及堆空间开销。 所以你的meegaString向量甚至不会接近完整的4Gb,甚至可能不会接近2Gb(如果构建为大型地址空间感知的应用程序,它可能会超过2Gb)。
现在关于安东尼阿诺德提到的“前期配置”问题,所有的STL集装箱都承诺了摊销运营时间。 std :: vector类承诺平均(即分期付款)push_back()操作将是常量时间(即O(1)),这意味着随着其内容越来越大,执行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 ()会越来越长矢量的数据越大。
矢量类模板实现了一个动态数组,它需要一个连续的内存块。
为了关闭这个话题 – 为了这个目的,可以使用列表容器,但是堆栈似乎是最好的解决方案。 然而,无论是与列表或堆栈,它仍然崩溃与相同的错误(现在附近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; }