Top和Free命令中的内存使用信息怎么那么怪
转自
http://linmingren.me/blog/2014/03/top%E5%92%8Cfree%E5%91%BD%E4%BB%A4%E4%B8%AD%E7%9A%84%E5%86%85%E5%AD%98%E4%BD%BF%E7%94%A8%E4%BF%A1%E6%81%AF%E6%80%8E%E4%B9%88%E9%82%A3%E4%B9%88%E6%80%AA/
这几天搞性能测试,在用Top和Free命令来查看进程所使用的内存信息时发现了一些以前没注意到的东西。先用下面这个最简单的例子来说明一下top中的VIRT和RES以及Swap所代表的意思。
#include <iostream> using namespace std; int main() { char c; char * buf; while (1) { cin >> c; //每次new 200M buf = new char[1024 * 1024 * 200]; } return 0; }
在我机器上运行后,按下第一个字符之前的Top的输出是 (进程的名字是Memory, 先ps出进程号,然后用top -p 进程号 查看)
KiB Mem: 3921504 total, 2642932 used, 1278572 free, 242396 buffers KiB Swap: 4065276 total, 0 used, 4065276 free, 1203440 cached PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 7033 dlin 20 0 12528 1064 896 S 0.0 0.0 0:00.00 Memory
Free的输出是
total used free shared buffers cached Mem: 3829 2584 1244 0 236 1179 -/+ buffers/cache: 1168 2661 Swap: 3969 0 3969
输入一个字符后,top的输出是
KiB Mem: 3921504 total, 2653400 used, 1268104 free, 242764 buffers KiB Swap: 4065276 total, 0 used, 4065276 free, 1208860 cached PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 7033 dlin 20 0 212m 1064 896 S 0.0 0.0 0:00.00 Memory
free的输出是
total used free shared buffers cached Mem: 3829 2593 1235 0 237 1181 -/+ buffers/cache: 1174 2654 Swap: 3969 0 3969
这时top中如果只看%MEM的话,就会以为这个进程没有用什么内存,虽然实际上已经分配了200M,而free中used的物理内存的大小几乎没变,结论是new出来的内存,如果你没有使用它,那么就不会驻留在物理内存中。怎么使用这块内存呢,直接用memset给它设些值就行。
把代码加一行,改成这样:
#include <iostream> #include <cstring> using namespace std; int main() { char c; char * buf; while (1) { cin >> c; //每次new 200M buf = new char[1024 * 1024 * 200]; //只使用其中的100M memset(buf,'a',1024 * 1024 * 100); } return 0; }
这次的top就看到%MEM有值了,而且驻留内存(RES)是100M,刚好是我们memset的大小。
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 7504 dlin 20 0 212m 101m 964 S 0.0 2.6 0:00.04 Memor
free的输出也可以看到used的内存多了差不多100M
total used free shared buffers cached Mem: 3829 2736 1093 0 238 1203 -/+ buffers/cache: 1295 2534 Swap: 3969 0 3969
到了这里VIRT和RES的含义就清晰了:
VIRT: 就是你代码new或者malloc的内存的大小
RES: 你真正使用的内存的大小,如果你new出来,但没有使用,那么这个值会比较小。
接下来看Swap的意思,其实从字面意思大概可以猜出来这应该是物理内存不够时,系统把一部分内存置换到硬盘上的大小。因为我们还没有用完物理内存,所以top命令输出中的Swap就是0. 让我们不断运行我们的程序,看看要分配几次200M才会让Swap的值不是0.当new了5G (注意物理内存只有不到3G多),使用了2.5G的时候去看top的输出,发现有500M (500776 used)的内存已经被置换到硬盘上去了,这时候我的电脑作什么都变得很慢(风扇的声音大了好多),因为这时候new的内存都是从硬盘映射过来的。
KiB Mem: 3921504 total, 3792944 used, 128560 free, 296 buffers KiB Swap: 4065276 total, 500776 used, 3564500 free, 182828 cached PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 7504 dlin 20 0 5212m 2.5g 204 S 0.0 67.9 0:01.35 Memor
在启动swap的64位系统上,想要搞个bad_alloc异常不是很容易。不过我们可以关闭swap,
sudo swapoff -a
terminate called after throwing an instance of 'std::bad_alloc' what(): std::bad_alloc gAborted (core dumped)
如果我们只new,而不使用内存,一样会得到bad_alloc异常,像下面改动后的代码,直接new 4G内存会马上出错 (前提是调用了swapoff)。
#include <iostream> #include <cstring> using namespace std; int main() { char c; char * buf; while (1) { cin >> c; //new 4G buf = new char[1024 * 1024 * 4000]; //只使用其中的100M //memset(buf,'a',1024 * 1024 * 100); } return 0; }
浙公网安备 33010602011771号