• linuxshell脚本记录进程内存变化top | VmRSS | VmSize(内存泄漏)


    linux--shell脚本记录进程内存变化VmRSS|VmSize(内存泄漏)

    1 介绍
    2 虚拟内存(Virtual Memory)与驻留内存(Resident Memory)
    2.1 虚拟内存(Virtual Memory)
    概述
    详述
    2.2 驻留内存(Resident Memory)
    3 top中的VIRT、RES和SHR
    3.1 VIRT--虚拟内存空间的大小
    3.2 RES--已经映射到物理内存空间的大小
    3.3 SHR--共享物理内存大小
    4 /proc/{pid}/status
    5 如下每10分钟统计一次
    参考
    1 介绍

    记录进程的内存增长情况,定位是否内存泄漏。

    2 虚拟内存(Virtual Memory)与驻留内存(Resident Memory)

    2.1 虚拟内存(Virtual Memory)

    概述

    虚拟内存是一个假象的内存空间,在程序运行过程中虚拟内存空间中需要被访问的部分会被映射到物理内存空间中。虚拟内存空间大只能表示程序运行过程中可访问的空间比较大,不代表物理内存空间占用也大。
    详述

    进程占用虚拟内存空间大并非意味着程序的物理内存也一定占用很大。**虚拟内存是操作系统内核为了对进程地址空间进行管理(process address space management)而精心设计的一个逻辑意义上的内存空间概念。**我们程序中的指针其实都是这个虚拟内存空间中的地址。比如我们在写完一段C++程序之后都需要采用g++进行编译,这时候编译器采用的地址其实就是虚拟内存空间的地址。因为这时候程序还没有运行,何谈物理内存空间地址?**凡是程序运行过程中可能需要用到的指令或者数据都必须在虚拟内存空间中。**既然说虚拟内存是一个逻辑意义上(假象的)的内存空间,为了能够让程序在物理机器上运行,那么必须有一套机制可以让这些假象的虚拟内存空间映射到物理内存空间(实实在在的RAM内存条上的空间)。这其实就是操作系统中页映射表(page table)所做的事情了。内核会为系统中每一个进程维护一份相互独立的页映射表。页映射表的基本原理是将程序运行过程中需要访问的一段虚拟内存空间通过页映射表映射到一段物理内存空间上,这样CPU访问对应虚拟内存地址的时候就可以通过这种查找页映射表的机制访问物理内存上的某个对应的地址。“页(page)”是虚拟内存空间向物理内存空间映射的基本单元。
    下图演示了虚拟内存空间和物理内存空间的相互关系,它们通过Page Table关联起来。其中虚拟内存空间中着色的部分分别被映射到物理内存空间对应相同着色的部分。而虚拟内存空间中灰色的部分表示在物理内存空间中没有与之对应的部分,也就是说灰色部分没有被映射到物理内存空间中。这么做也是本着“按需映射”的指导思想,因为虚拟内存空间很大,可能其中很多部分在一次程序运行过程中根本不需要访问,所以也就没有必要将虚拟内存空间中的这些部分映射到物理内存空间上。

    2.2 驻留内存(Resident Memory)

    驻留内存,顾名思义是指那些被映射到进程虚拟内存空间的物理内存。上图中,**在系统物理内存空间中被着色的部分都是驻留内存。**比如,A1、A2、A3和A4是进程A的驻留内存;B1、B2和B3是进程B的驻留内存。进程的驻留内存就是进程实实在在占用的物理内存。**一般我们所讲的进程占用了多少内存,其实就是说的占用了多少驻留内存而不是多少虚拟内存。**因为虚拟内存大并不意味着占用的物理内存大。

    3 top中的VIRT、RES和SHR

    3.1 VIRT–虚拟内存空间的大小

    VIRT表示的是进程虚拟内存空间大小。对应到图1中的进程A来说就是A1、A2、A3、A4以及灰色部分所有空间的总和。也就是说VIRT包含了在已经映射到物理内存空间的部分和尚未映射到物理内存空间的部分总和。

    3.2 RES–已经映射到物理内存空间的大小

    RES的含义是指进程虚拟内存空间中已经映射到物理内存空间的那部分的大小。对应到图1中的进程A来说就是A1、A2、A3以及A4几个部分空间的总和。所以说,看进程在运行过程中占用了多少内存应该看RES的值而不是VIRT的值。

    3.3 SHR–共享物理内存大小

    SHR是share(共享)的缩写,它表示的是进程占用的共享内存大小。在上图1中我们看到进程A虚拟内存空间中的A4和进程B虚拟内存空间中的B3都映射到了物理内存空间的A4/B3部分。咋一看很奇怪。为什么会出现这样的情况呢?其实我们写的程序会依赖于很多外部的动态库(.so),比如libc.so、libld.so等等。这些动态库在内存中仅仅会保存/映射一份,如果某个进程运行时需要这个动态库,那么动态加载器会将这块内存映射到对应进程的虚拟内存空间中。**多个进程之间通过共享内存的方式相互通信也会出现这样的情况。**这么一来,就会出现不同进程的虚拟内存空间会映射到相同的物理内存空间。这部分物理内存空间其实是被多个进程所共享的,所以我们将他们称为共享内存,用SHR来表示。某个进程占用的内存除了和别的进程共享的内存之外就是自己的独占内存了。所以要计算进程独占内存的大小只要用RES的值减去SHR值即可。

    4 /proc/{pid}/status

    在Linux中,用户进程在/proc/{pid}/status文件中记录了该进程的内存使用实时情况。
    VmSize:
    虚拟内存大小。
    整个进程使用虚拟内存大小,是VmLib, VmExe, VmData, 和 VmStk的总和。
    VmLck:
    虚拟内存锁。
    进程当前使用的并且加锁的虚拟内存总数
    VmRSS:
    虚拟内存驻留集合大小。
    这是驻留在物理内存的一部分。它没有交换到硬盘。它包括代码,数据和栈。
    VmData:
    虚拟内存数据。
    堆使用的虚拟内存。
    VmStk:
    虚拟内存栈
    栈使用的虚拟内存
    VmExe:
    可执行的虚拟内存
    可执行的和静态链接库所使用的虚拟内存
    VmLib:
    虚拟内存库
    动态链接库所使用的虚拟内存
    5 如下每10分钟统计一次

    # desc: get process meminfo every 10 mins.
    # author: worthsen

    #!/bin/sh

    pid=3158
    interval=600

    echo $pid
    while true
    do
    DATE=`date '+%Y-%m-%d-%H:%M:%S'`
    echo $DATE >> proc_memlog.txt
    #echo VmRSS: >> proc_memlog.txt
    cat /proc/$pid/status|grep -e VmRSS >> proc_memlog.txt
    cat /proc/$pid/status|grep -e VmSize >> proc_memlog.txt
    echo $blank >> proc_memlog.txt
    sleep $interval
    done

    参考

    1、
    2、linux top命令VIRT,RES,SHR,DATA的含义
    3、进程的虚拟内存,物理内存,共享内存
    4、观察进程的内存占用情况
    5、top命令介绍、实存(RES) 与 虚存(VIRT)区别 ——VIRT持续增长,记一次内存泄漏定位
    6、worthsen–linux–内存泄漏介绍与工具

    文章知识点与官方知识档案匹配,可进一步学习相关知识
    ————————————————
    版权声明:本文为CSDN博主「worthsen」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/qq_38880380/article/details/120234641

  • 相关阅读:
    SpringBoot-Mysql模板多数据源加载
    SpringCloud-动态配置变化监控-获取变化(支持Config、Nacos)
    SpringBoot-ElasticJob封装快速上手使用(分布式定时器)
    关键字(标签)提示组件——拼音、汉字混合搜索
    写一个高性能的敏感词检测组件
    一个文件搞定Asp.net core 3.1动态页面转静态页面
    浅谈C#在网络波动时防重复提交
    对RC4算法进行改写,新的加密算法RCX。
    【ToolGood.Words】之【StringSearch】字符串搜索——基于BFS算法
    万能解决方案之彻底解决macOS cocoapods环境的所有问题
  • 原文地址:https://www.cnblogs.com/wanghuaijun/p/15916751.html
Copyright © 2020-2023  润新知