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 zombie: 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 st

0x4: 第四行

1. KiB Mem: 内存
2. 2048496 total: 物理内存总量
3. 226356 used: 使用的物理内存量
4. 1822140 free: 空闲的物理内存量
5. 34060 buffers: 用作内核缓存的物理内存量

0x5: 第五行

1. KiB Swap: 交换空间   
2. 0 total: 交换区总量
3. 0 used: 使用的交换区量
4. 0 free: 空闲的交换区量
5. 117004 cached Mem: 缓冲交换区总量

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
http://blog.csdn.net/u011547375/article/details/9851455

 

8. Glibc、Glibc运行时库内存池管理对进程内存使用统计情况的影响

在Linux下,进程使用C库进行内存申请、释放,Glibc在内部维护了一套内存池管理机制,接管了应用程序的内存申请/释放行为

Copyright (c) 2015 LittleHann All rights reserved

posted @ 2017-04-23 10:19  郑瀚Andrew  阅读(1543)  评论(0编辑  收藏  举报