我正在运行这段代码:
#include <iostream>
#include <cstddef>
int main(int argc, char *argv[]){
int a1=0, a2=0;
int a3,a4;
int b1=++a1;
int b2=a2++;
int*p1=&a1;
int*p2=&++a1;
size_t st;
ptrdiff_t pt;
int i=0;
while(true){
printf("i: %d",i++);
}
printf("\n\ni now is: %d\n",i);
return 0;
}
为什么我观察到图像内存(fiolet)如此减少: 图例:
我制作了这个通用的 Win32 项目,而不是 CLR。 我更改了代码,所以我会看到 int 何时最终变为负值。现在 while() 是:
int i=0;
while(0<++i){
printf("i: %d",i++);
}
printf("\n\ni now is: %d\n",i);
很奇怪:请看仅仅 30000 次迭代后发生了什么。为什么我们会在图像内存中看到这些波动?我现在可以看到,这可能与 VMMap 本身有关,因为它仅在我选择“启动并跟踪新进程”时发生,而不是在“查看正在运行的进程”并指向从 VS2010 触发的运行 exe 时发生。这是“启动和跟踪”过程的屏幕:
我还观察到大量的内存分页,这大致是从图像下降开始的(这种分页几乎加速并迅速触发了 RAM 限制,我已将其设置为 2GB): 这是一个仅“查看”的运行过程(从 VS2010 运行):
那么这里可能会发生一些与 .NET 应用程序的内存管理有关的问题? 我仍在等待我的 int 跨越两个补码的边界。
好吧......我必须再次编辑:事实证明,正如之前所想的那样 - 当仅查看(未启动)进程时也存在内存图像减少效应。下面附上相同过程 10 分钟后的图片(仍在等待将 int 转为负数):
这里是:
所以我机器上最大的正 2-补码是 2 147 483 647 最小的负值是 -2 147 483 648,这样很容易验证:
#include <limits>
const int min_int = std::numeric_limits<int>::min();
const int max_int = std::numeric_limits<int>::max();
它给了我相同的结果:-2 147 483 648 和 2 147 483 647
回到起点 当我评论除 while() 循环之外的所有内容时 - 同样的事情发生了:图像在进程运行大约 10 分钟后减少,所以不是无用的代码导致了这个。但是什么?
最佳答案
工作集主要由操作系统控制。你的代码所做的只是它在决定是增加还是削减你的工作集时考虑的一个因素。其他因素包括您的应用程序是否在前台、它有多活跃、堆算法有多贪婪、由于其他进程的需求而存在多少内存压力等。这是设计使然。
下降可能与 Windows 选择修剪您的工作集有关。由于最初加载的大部分代码可能只是用于初始化,不涉及循环,因此操作系统很容易根据 LRU 算法回收图像页面。
请注意,分配给图像大小的工作集并不是唯一被修剪的部分。
关于c++ - 内存影像减少,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10985690/