Linux top、VIRT、RES、SHR、SWAP(S)、DATA Memory Parameters Detailed
catalog
1. Linux TOP指令
2. VIRT -- Virtual Image (KB)
3. RES -- Resident size (KB)
4. SHR -- Shared Memory size (KB)
5. SWAP -- Swapped size (KB)
6. DATA -- Data+Stack size (KB)
7. 进程内存统计情况内核态表示
8. Glibc、Glibc运行时库内存池管理对进程内存使用统计情况的影响
1. Linux TOP指令
top 命令是最流行的性能监视工具之一,我们必需了解。它是一个优秀的交互式工具,用于监视性能。它提供系统整体性能,但报告进程信息才是 top 命令的长处。top 命令交互界面如下图所视
top 界面分为两个部份,光标上面部份显示关于系统整体性能,光标下面部份显示各进程信息。光标所在处是用来输入操作命令的
0x1: 第一行
1. top: 名称
2. 15:21:20: 系统当前时间
3. up: 1 day
4. 2:10: 系统开机到现在经过了多少时间
5. 1 user: 当前1个用户在线
6. load average: 0.00, 0.01, 0.05: 系统1分钟、5分钟、15分钟的CPU负载信息
0x2: 第二行
1. Tasks: 任务
2. 104 total: 当前有104个任务,即104个进程
3. 1 running: 1个进程正在运行
4. 103 sleeping: 103个进程睡眠
5. 0 stopped: 0个停止的进程
6. 0
0x3: 第三行
1. %Cpu(s): 显示CPU总体信息
2. 0.2 us: 进程占用CPU时间百分比为0.2%
3. 0.2 sy: 内核占用CPU时间百分比为0.2%
4. 0.0 ni: renice值为负的任务的用户态进程的CPU时间百分比,nice是优先级的意思
5. 99.5 id: 空闲CPU时间百分比
6. 0.0 wa: 等待I/O的CPU时间百分比
7. 0.0 hi: CPU硬中断时间百分比
8. 0.0 si: CPU软中断时间百分比
9. 0.2
0x4: 第四行
1. KiB Mem: 内存
2. 2048496 total: 物理内存总量
3. 226356 used: 使用的物理内存量
4. 1822140 free: 空闲的物理内存量
5. 34060
0x5: 第五行
1. KiB Swap: 交换空间
2. 0 total: 交换区总量
3. 0 used: 使用的交换区量
4. 0 free: 空闲的交换区量
5. 117004
0x6: 第六行
1. PID: 进程的ID
2. USER: 进程的所有者
3. PR: 进程的优先级别,越小优先级别越高
4. NI: NInice值
5. VIRT: 进程占用的虚拟内存
6. RES: 进程占用的物理内存
7. SHR: 进程使用的共享内存
8. S: 进程的状态
1) S表示休眠
2) R表示正在运行
3) Z表示僵死状态
4) N表示该进程优先值为负数
9. %CPU: 进程占用的CPU使用率
10. %MEM: 进程使用的物理内存和总内存的百分比
11. TIME+: 该进程启动后占用的总的CPU时间,即占用CPU使用时间的累加值
12. COMMAND: 进程启动命令名称
Relevant Link:
http://os.51cto.com/art/201108/285581.htm
2. VIRT -- Virtual Image (KB)
Thetotal amount of virtual memory used by the task. It includes all code, data andshared libraries plus pages that have been swapped out. (一个任务所使用的虚拟内存的总数。它包括所有的代码,数据和共享库,加上已换出的页面)
VIRT = SWAP +RES (公式1)
从本质上讲,虚拟内存并不能完全说明一个进程的内存占用情况,因为并不是所有虚拟内存对一一映射到物理内存页
Relevant Link:
http://javawind.net/p131
3. RES -- Resident size (KB)
The non-swappedphysical memory a task has used. (一个任务正在使用的没有交换的物理内存)我们一般称为驻留内存空间,也即一个进程实际占用的物理内存页
RES = CODE + DATA
4. SHR -- Shared Memory size (KB)
The amount ofshared memory used by a task. It simply reflects memory that could bepotentially shared with other processes. (一个任务使用共享内存的总数。它只是反映可能与其它进程共享的内存)也就是这个进程使用共享内存的大小
5. SWAP -- Swapped size (KB)
Theswapped out portion of a task’s total virtual memory image. (换出一个任务的总虚拟镜像的一部分)只是说明了交换的内存来自虚拟内存,但没说明把什么样的内存交换出去
6. DATA -- Data+Stack size (KB)
Theamount of physical memory devoted to other than executable code, also known asthe ’data resident set’ size or DRS. (除可执行代码以外的物理内存总量,也被称为数据驻留集或DRS
7. 进程内存统计情况内核态表示
top里面描述进程内存使用量的数据来源于/proc/$pid/statm这个文件,我们通过观察kernel的代码来理解它们的本质含义,Linux通过一个叫做 task_statm 的函数来返回进程的内存使用状况
/source/fs/proc/task_mmu.c
int task_statm(struct mm_struct *mm, int *shared, int *text, int *data, int *resident)
{
//shared代表了page cache里面实际使用了的物理内存的页数
*shared = get_mm_counter(mm, file_rss);
//text代表了代码所占用的页数
*text = (PAGE_ALIGN(mm->end_code) - (mm->start_code & PAGE_MASK)) >> PAGE_SHIFT;
//data是总虚拟内存页数减去共享的虚拟内存页数
*data = mm->total_vm - mm->shared_vm;
//resident是所有在使用的物理内存的页数
*resident = *shared + get_mm_counter(mm, anon_rss);
//mm->total_vm;是进程虚拟内存的寻址空间大小
return mm->total_vm;
}
上面的数值最后会通过 procfs输出 到/proc/$pid/statm中去,他们与top显示的数值对应关系如下
SHR: shared
RES: resident
VIRT: mm->total_vm
CODE: code
DATA: data
/*
[root@iZ23lobjjltZ ~]# cat /proc/434/statm
3160 195 99 18 0 113 0
*/
0x1: 示例CODE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <pthread.h>
const int BUFF_SIZE = 1 << 23;
const int SHARED_SIZE = 1 << 24;
const int SHM_TEST_ID = 888;
//4 static char GTestMem[1<<20];
//3 char GTestMem1[1<<20];
void TestMalloc()
{
//申请一段8M的栈空间
char szTemp[BUFF_SIZE];
//申请一段8M的堆空间
char* pszNew = (char*)malloc(BUFF_SIZE * sizeof(char));
if (pszNew == NULL)
{
printf("Malloc memory %d failed.\n", BUFF_SIZE);
exit(-1);
}
//1 memset(szTemp, 'q', BUFF_SIZE);
//1 memset(pszNew, 'w', BUFF_SIZE);
//2 memset(szTemp, 'q', BUFF_SIZE / 4);
//2 memset(pszNew, 'w', BUFF_SIZE / 4);
while (1)
{
sleep(10);
}
}
void ShMemory()
{
char szTemp[BUFF_SIZE];
char* pszNew = (char*)malloc(BUFF_SIZE * sizeof(char));
if (pszNew == NULL)
{
printf("Malloc memory %d failed.\n", BUFF_SIZE);
exit(-1);
}
int fdShMem = shmget(SHM_TEST_ID, SHARED_SIZE, 0666|IPC_CREAT);
if (fdShMem == -1)
{
printf("Create shared memory failed.\n");
exit(-1);
}
void* pSHM = shmat(fdShMem, NULL, 0);
if ( (int)pSHM == -1)
{
printf("Attach shared memory failed.\n");
exit(-1);
}
memset(pSHM, 't', SHARED_SIZE / 4);
while (1)
{
sleep(10);
}
}
void MallocLeak()
{
char szTemp[BUFF_SIZE];
// for (int i = 0; i < BUFF_SIZE / 4; i++)
// szTemp[i] = i % 255;
sleep(30);
char* pszNew = NULL;
while (1)
{
pszNew = (char*)malloc(BUFF_SIZE * sizeof(char));
if (pszNew == NULL)
{
printf("Malloc memory %d failed.\n", BUFF_SIZE);
exit(-1);
}
// memset(pszNew, 7, BUFF_SIZE / 4);
// free(pszNew);
sleep(5);
}
}
int main(int argc, char* argv[])
{
TestMalloc();
// ShMemory();
return 0;
}
Relevant Link:
http://wenku.baidu.com/view/1cb3338683d049649b6658a3.html
8. Glibc、Glibc运行时库内存池管理对进程内存使用统计情况的影响
在Linux下,进程使用C库进行内存申请、释放,Glibc在内部维护了一套内存池管理机制,接管了应用程序的内存申请/释放行为
Copyright (c) 2015 LittleHann All rights reserved