zoukankan      html  css  js  c++  java
  • 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.
    ", 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.
    ", BUFF_SIZE);
            exit(-1);
        }
    
        int  fdShMem = shmget(SHM_TEST_ID, SHARED_SIZE, 0666|IPC_CREAT);
        if (fdShMem == -1)
        {
            printf("Create shared memory failed.
    ");
            exit(-1);
        }
    
        void*  pSHM = shmat(fdShMem, NULL, 0);
        if ( (int)pSHM == -1)
        {
            printf("Attach shared memory failed.
    ");
            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.
    ", 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

  • 相关阅读:
    logback配置模板
    mail
    jpa,querydsl
    加密签名
    angular2快速开始
    主从复制
    随笔
    缺货源的小伙伴们 我发现一个超级好的货源供应链 分享给大家
    canal+kafka+logstash+es 架构 logstash的配置
    golang 根据图片url获取图片尺寸
  • 原文地址:https://www.cnblogs.com/LittleHann/p/4522855.html
Copyright © 2011-2022 走看看