我创build了一个有意识的内存泄漏来向那些不久将要学习指针的人展示一个点。
int main() { while (1) { int *a = new int [2]; //delete [] a; } }
如果在没有注释的代码的情况下运行,内存保持低位,并不像预期的那样上升。 但是,如果这样运行,那么在具有2GB RAM的机器上,内存使用率会迅速上升到大约1.5GB,或者系统没有使用的任何内存。 一旦达到这一点,CPU使用率(之前是最大的)会大大下降,内存使用率也会下降到100MB左右。
究竟是什么造成了这种干预行动(如果有什么比“Windows”更具体的东西,这将是伟大的),为什么程序不占用CPU会循环,但不终止? 它似乎卡在循环结束和主结束之间。
Windows XP,GCC,MinGW。
可能发生的是您的代码分配所有可用的物理RAM。 当达到该限制时,系统开始在交换文件上分配空间。 这意味着它(几乎)不断地在磁盘上等待,所以它的CPU使用率下降到(几乎)为零。
系统可以很容易地跟踪它实际上没有写入它分配的内存的事实,所以当它需要被存储在交换文件上时,它只会产生一个小的记录,基本上说“进程X有N个字节的未初始化存储“,而不是实际上将所有数据复制到硬盘驱动器(但我不确定这一点,它可能取决于您使用的确切系统)。
用意思蒙托亚的话来说,“我不认为这意味着你的想法。” Windows任务管理器不显示您正在查找的内存使用情况数据。
“Mem Usge”列显示与进程的工作集大小(或驻留集大小)相关的内容。 也就是说,“内存使用情况”显示一个与当前分配给您的进程的物理内存量相关的数字。
“虚拟机大小”列显示一个与虚拟内存子系统完全无关的数字(它实际上是进程分配的私有堆的大小。
尝试使用不同的工具来使用虚拟内存。 我建议Process Explorer 。
我想当程序耗尽可用的物理内存时,它开始使用磁盘(虚拟)内存,并且变得非常慢,看起来好像它是不活动的。 尝试添加一些速度可视化:
int counter = 0; while (1) { int *a = new int [2]; ++counter; if (counter % 1000000 == 0) std::cout << counter << '\n' }
XP任务管理器中的默认内存列是进程工作集的大小(分配给该进程的物理内存量),而不是实际的内存使用量。
http://msdn.microsoft.com/en-us/library/windows/desktop/ms684891%28v=vs.85%29.aspx
http://blogs.msdn.com/b/salvapatuel/archive/2007/10/13/memory-working-set-explored.aspx
任务管理器的“Mem Usage”列可能是这个问题中的一些答案所解释的“工作集”,不过说实话,我仍然对任务管理器在不同版本间如何引用内存感到困惑。 这个值上升/下降,因为在任何给定的时间显然实际上并没有使用太多的内存。 如果你看“VM大小”,你应该看到它不断增加,直到发生不好的事情。
您也可以尝试使用Process Explorer ,我很容易理解它是如何显示内容的。
有几件事情:首先,如果您一次只分配2个int
,则可能需要几个小时才能注意到总内存使用量正在上升。 其次,在很多系统上,只有在实际访问内存之后,才会提交分配; 地址空间可能被保留,但是你并没有真正的内存(如果你尝试访问内存,程序将会崩溃,而且没有任何可用的内存)。
如果你想模拟一个泄漏,我建议一次至少分配一个页面,如果不是更多,并且在每个分配的页面中至少写入一个字节。