linux top命令 实存(RES)与虚存(VIRT)详解

今天被人问到 linux系统里top命令输出的VIRT这个虚拟内存是从哪分配的呢?
有点懵,所以找了找资料,翻了翻博客

一、基础概念

VIRT:

1、进程“需要的”虚拟内存大小,包括进程使用的库、代码、数据,以及malloc、new分配的堆空间和分配的栈空间等;
2、假如进程新申请10MB的内存,但实际只使用了1MB,那么它会增长10MB,而不是实际的1MB使用量。
3、VIRT = SWAP + RES

RES:

1、进程当前使用的内存大小,包括使用中的malloc、new分配的堆空间和分配的栈空间,但不包括swap out量;
2、包含其他进程的共享;
3、如果申请10MB的内存,实际使用1MB,它只增长1MB,与VIRT相反;
4、关于库占用内存的情况,它只统计加载的库文件所占内存大小。
5、RES = CODE + DATA

SHR:

1、除了自身进程的共享内存,也包括其他进程的共享内存;
2、虽然进程只使用了几个共享库的函数,但它包含了整个共享库的大小;
3、计算某个进程所占的物理内存大小公式:RES – SHR;
4、swap out后,它将会降下来。

二、测试

(1) 使用堆分配内存, 进行测试:

1	#include <iostream>
 2 #include <stdio.h>
 3 #include <string.h>
 4 
 5 int main()
 6 {
 7     int test = 0;
 8     //分配512M, 未使用
 9     char * p = new char [1024*1024*512];
10     scanf("%d", &test); //等待输入
11 
12     //使用10M
13     memset(p, 0, 1024 * 1024 * 10);
14     scanf("%d", &test); //等待输入
15 
16     //使用50M
17     memset(p, 0, 1024 * 1024 * 50);
18     scanf("%d", &test); //等待输入
19     delete [] p;
20     return 0;
21 }

执行:

new 512M后,VIRT/RES

virt 过高java virt-top_ios


使用10M后,VIRT/RES

virt 过高java virt-top_共享库_02


使用50M后,VIRT/RES

virt 过高java virt-top_virt 过高java_03


(2) 使用栈分配内存进行测试:

1 #include <iostream>
 2 #include <stdio.h>
 3 #include <string.h>
 4 
 5 int main()
 6 {
 7     int test = 0;
 8     //20M栈, 未使用
 9     char p[1024*1024*20];
10     scanf("%d", &test);    //等待输入
11 
12     //使用10M
13     memset(p, 0, 1024 * 1024 * 10);
14     scanf("%d", &test);    //等待输入
15     return 0;
16 }

执行:

栈上申请20M

virt 过高java virt-top_#include_04


使用10M

virt 过高java virt-top_ios_05

  1. 总结

堆、栈分配的内存,如果没有使用是不会占用实存的,只会记录到虚存。
如果程序占用实存比较多,说明程序申请内存多,实际使用的空间也多。
如果程序占用虚存比较多,说明程序申请来很多空间,但是没有使用。