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

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–内存泄漏介绍与工具

### 回答1: Linuxshell脚本可以利用内存和CPU来执行各种操作和任务,以下是几种使用内存和CPU的情况: 1. 内存使用:在shell脚本中,您可以使用变量和数组来存储数据,这些数据会在内存中占用一定的空间。如果您需要处理大量数据,您可能需要分配更多的内存来存储数据。您可以使用Linux系统提供的free命令来查看系统内存使用情况。 2. CPU占用:在shell脚本中,您可以运行各种命令和程序,这些命令和程序会占用系统的CPU资源。如果您需要执行一些耗费CPU资源的任务,您可能需要在编写脚本时考虑到这一点,并尽可能优化您的代码以最大化CPU使用效率。您可以使用Linux系统提供的top命令来查看系统CPU使用情况,并找出哪些进程占用了大量的CPU资源。 需要注意的是,在编写shell脚本时,应该尽可能地使用系统资源,避免浪费资源和影响系统性能。另外,您还可以使用Linux系统提供的一些工具来优化您的shell脚本,如使用awk和sed来处理文本数据,使用xargs和parallel来并行执行命令等。 ### 回答2: 要运行输出可用内存和CPU占用情况,可以使用Linuxshell脚本来实现。 首先,使用内存信息的命令是`free`,它可以显示系统的内存使用情况。可以使用`grep`和`awk`命令来提取可用内存的信息并进行格式化输出。 ```shell # 获取可用内存信息并格式化输出 memory_info=$(free -m | grep Mem | awk '{print $4}') echo "可用内存:${memory_info} MB" ``` 接下来,获取CPU占用情况可以使用`top`命令。`top`命令可以显示系统的实时进程和CPU使用情况,但默认情况下会一直显示,需要使用`head`和`grep`命令来筛选出CPU占用信息并进行格式化输出。 ```shell # 获取CPU占用信息并格式化输出 cpu_info=$(top -n 1 -b | head -n 12 | grep '%Cpu' | awk '{print $2}') echo "CPU占用:${cpu_info}%" ``` 最后,将上述代码整合到一个shell脚本文件中,给文件添加执行权限,并运行即可得到可用内存和CPU占用情况的输出。 ```shell #!/bin/bash # 获取可用内存信息并格式化输出 memory_info=$(free -m | grep Mem | awk '{print $4}') echo "可用内存:${memory_info} MB" # 获取CPU占用信息并格式化输出 cpu_info=$(top -n 1 -b | head -n 12 | grep '%Cpu' | awk '{print $2}') echo "CPU占用:${cpu_info}%" ``` 以上的脚本可以在Linux系统上运行,并输出可用内存和CPU占用情况。 ### 回答3: 要求在Linuxshell脚本中运行并输出可用内存和CPU占用情况,可以使用下面的方法: 1. 通过`free`命令获取系统的内存使用情况。使用`-h`选项以人类可读的方式显示内存使用情况,`awk`命令可以帮助我们提取所需的信息。可以使用以下命令来获取可用内存的值: ``` free -h | awk '/Mem/ {print $7}' ``` 该命令先运行`free -h`命令获取内存信息,然后使用`awk`过滤出包含"Mem"的行,并打印第7列的值,即可用内存。 2. 通过`top`命令获取系统的CPU占用情况。我们可以使用`top`命令的`-n1`选项,表示只运行一次,并且使用`-b`选项以批处理模式运行,将输出结果直接输出给其他命令进行处理。利用`grep`和`awk`命令可以提取所需的CPU使用信息。以下是获取CPU占用百分比的命令示例: ``` top -n1 -b | grep "Cpu(s)" | awk '{print $2+$4}' ``` 此命令运行`top`命令获取CPU信息,并且使用`grep`过滤出包含"Cpu(s)"的行,然后使用`awk`打印第2列和第4列的和,即CPU占用。 综上,我们可以将上述两个命令结合在一起,编写一个shell脚本,如下所示: ```shell #!/bin/bash # 获取可用内存 free_mem=$(free -h | awk '/Mem/ {print $7}') # 获取CPU占用 cpu_usage=$(top -n1 -b | grep "Cpu(s)" | awk '{print $2+$4}') # 输出结果 echo "可用内存: $free_mem" echo "CPU占用: $cpu_usage%" ``` 保存脚本并赋予执行权限,然后通过运行脚本来获取可用内存和CPU占用情况。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

worthsen

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值