如何衡量应用程序或进程的实际内存使用情况?


712

这个问题在这里详细介绍。

您如何衡量Linux中应用程序或进程的内存使用情况?

了解Linux上的内存使用的博客文章中可以看出ps这不是用于此目的的准确工具。

为什么ps是“错”

根据您的看法,它ps不会报告进程的实际内存使用情况。它的真正作用是显示如果每个进程是唯一运行的进程每个进程将占用多少实际内存。当然,一台典型的Linux机器在任何给定的时间都有几十个进程在运行,这意味着报告的VSZ和RSS编号ps几乎肯定是错误的


6
现在,这个问题可能属于serverfault.com,尽管它告诉我它“太老了,无法迁移”。尽管实际上并不想关闭
thomasrutter 2012年


2
实际上ps甚至都没有显示-它显示了虚拟内存和常驻内存的数量,其中virtual是该进程理论上可以使用的最大内存量,它是唯一的进程(从未如此),使用了分配给它的每个页面(从未发生过)并且没有映射或取消映射任何页面(不太可能)。而常驻表示当前有多少虚拟内存映射到物理上。virt > usage > res但是,通常在64位系统上virt ~= res*10,范围非常广泛。
Dima Tisnek

5
链接文章的摘录完全是胡说八道。RSS是实际使用的物理内存,即使进程是唯一运行的VSZ,VSZ也可能转换为物理内存,也可能不会转换为物理内存。
David Schwartz

Answers:


356

使用ps或类似的工具,您将只获得该进程分配的内存页数量。这个数字是正确的,但是:

  • 不反映应用程序实际使用的内存量,仅反映为其保留的内存量

  • 如果页面被共享(例如由多个线程共享或通过使用动态链接的库)可能会产生误导

如果您真的想知道应用程序实际使用的内存量,则需要在分析器中运行它。例如,valgrind可以为您提供有关已用内存量的信息,更重要的是,您可以了解程序中可能的内存泄漏。valgrind的堆分析器工具称为“ massif”:

Massif是堆分析器。它通过对程序堆进行定期快照来执行详细的堆分析。它生成一个图表,显示随时间推移的堆使用情况,包括有关程序的哪些部分负责最多内存分配的信息。该图由文本或HTML文件补充,该文本或HTML文件包含更多信息,用于确定分配最大内存的位置。Massif运行的程序比正常运行慢约20倍。

valgrind文档中所述,您需要通过valgrind运行程序:

valgrind --tool=massif <executable> <arguments>

Massif写入内存使用情况快照的转储(例如massif.out.12345)。这些提供了(1)内存使用的时间表,(2)每个快照,记录了程序存储器中的分配位置。massif-visualizer是分析这些文件的一种出色的图形工具。但是我发现ms_printvalgrind附带的一个简单的基于文本的工具已经很有帮助。

要查找内存泄漏,请使用memcheckvalgrind 的(默认)工具。


44
为了解释valgrind生成的结果,我建议使用alleyoop。不太花哨,它只是告诉您查找泄漏源所需的知识。一对不错的实用程序。

6
(a)项正确。通过调用malloc(),new等,已使用的页面和应用程序实际分配的内存之间存在差异。常驻用法仅显示RAM中常驻的分页内存量。
jcoffland 2010年

63
这真的不能说明如何使用valgrind获得内存使用情况吗?
马特·乔纳

11
默认的valgrind工具memcheck可用于检测内存泄漏,但实际上并不是内存分析器。为此,您需要valgrind --tool = massif。
托德

3
@DavidSchwartz我看不出您的陈述与我的说法相矛盾。我觉得您对我“错”的观点过于关心,而不是真正阅读我的讲话。我的意思是,RSS不能正确衡量应用程序的实际内存使用情况,而您在最后两句话中也提到了同样的观点。真的,您甚至以为我是首先提出RSS缩减的原因是什么?以便您将其拼写回我,以证明我所指的确切内容是“错误的”吗?你对我的态度很累。
ypnos

280

尝试使用pmap命令:

sudo pmap -x <process pid>

45
使用sudo运行,否则不显示错误,并且不显示消耗的内存。
马特(Matt)

22
在OSX上不存在(适用于所有来自google的人)
jcollum 2016年

3
这是问题的完整答案!ps。在我的shell中,pmap无需sudo即可读取进程。
MasterControlProgram

7
对于OS X(看似不是OP的问题),您可以使用vmmap(1)
jrg

注意:给出的答案与gnome-system-monitor
ribamar

190

很难确定,但是这里有两个可以帮助的“接近”的事情。

$ ps aux 

将为您提供虚拟尺寸(VSZ)

您还可以从/ proc文件系统获取详细的统计信息,方法是转到 /proc/$pid/status

最重要的是VmSize,它应该接近ps aux给出的值。

/ proc / 19420 $猫的状态
名称:Firefox
状态:S(正在睡觉)
Tgid:19420
点数:19420
PPid:1
示踪剂:0
Uid:1000 1000 1000 1000
吉德:1000 1000 1000 1000
FD尺寸:256
群组:4 6 20 24 25 29 30 44 46 107 109 115 124 1000 
VmPeak:222956 kB
Vm大小:212520 kB
VmLck:0 kB
VmHWM:127912 kB
VmRSS:118768 kB
VmData:170180 kB
VmStk:228 kB
VmExe:28 kB
VmLib:35424 kB
VmPTE:184 kB
线程:8
信号量:0/16382
签名:0000000000000000
ShdPnd:0000000000000000
信号量:0000000000000000
签名:0000000020001000
签名:000000018000442f
CapInh:0000000000000000
CapPrm:0000000000000000
CapEff:0000000000000000
Cpus_allowed:03
Mems_allowed:1
manual_ctxt_switches:63422
nonvoluntary_ctxt_switches:7171


21
我想念什么吗?这个问题问到,鉴于ps中报告的VSZ和RSS具有误导性,因此如何更好地衡量进程的内存使用情况。您的答案详细说明了如何查找VSZ-与被误导的相同值。
thomasrutter

16
@thomasrutter是的,您缺少原始问题(修订版1),该问题已被编辑了几次,而且已经很旧了(2008年)。最初的问题只是询问如何衡量进程的内存使用情况。但是,如果事情已经过时,则可以随意编辑问题和答案。:)
DustinB

1
注意:给出的答案与gnome-system-monitor
ribamar

131

在最新版本的linux中,使用smaps子系统。例如,对于PID为1234的进程:

cat /proc/1234/smaps

它会准确告诉您当时它正在使用多少内存。更重要的是,它将内存划分为私有内存和共享内存,因此您可以知道程序实例正在使用多少内存,而无需包括程序多个实例之间共享的内存。


我想这pmap是一个更简单的界面。
ribamar

126

没有简单的方法可以计算出来。但是有些人试图获得一些好的答案:


nice输出了完整的内存和进程列表
Rubytastic,

非常好,分组非常智能。
罗默2014年

是的,确实很好。我觉得ps_memsmem最终用户的措施是非常有用的,而如。pmap的非常详细的输出是针对开发人员的...允许检索Firefox的每种字体,插件,libs的内存使用情况。谢谢大家。@ bash,@ thomasruther。
tuk0z

这是迄今为止唯一与输出匹配的一项gnome-system-monitor
ribamar

110

使用smem,它是ps的替代方法,后者可计算每个进程的USS和PSS。您想要的可能是PSS。

  • USS-唯一集大小。这是唯一的这一过程非共享存储器的量(认为它作为ü独特存储器)。它不包括共享内存。因此,这将低于-报告进程使用的内存量,但是在您要忽略共享内存时很有用。

  • PSS-比例集大小。这就是你想要的。它将唯一内存(USS)与其共享内存的比例除以共享该内存的进程数,然后将它们加在一起。因此,它将为您准确表示每个进程使用了​​多少实际物理内存-共享内存真正表示为共享。考虑一下P是用于物理内存的。

这与ps和其他实用程序报告的RSS相比如何:

  • RSS-居民集大小。这是每个进程使用的共享内存加上未共享内存的数量。如果有任何进程共享内存,这将过量报告实际使用的内存量,因为对同一共享内存的计数将不止一次-在共享同一内存的其他进程中再次出现。因此,这是相当不可靠的,尤其是在高内存进程具有大量fork的情况下-这在服务器中很常见,例如Apache或PHP(fastcgi / FPM)进程。

注意:smem还可以(可选)输出图形,例如饼图等。IMO,您不需要任何这些。如果您只想像使用ps -A v一样从命令行使用它,则无需安装python-matplotlib建议的依赖项。


2
关于RSS的关键一点是,如今大多数应用程序共享许多代码页。每个共享库(例如libc和libstdc ++)都将计入使用它的每个进程。而且,如果有多个正在运行的流程实例,那么所有这些代码都会被重复计算。
David C.

1
准确地讲,这就是为什么RSS在每个进程的实际物理内存方面进行过多报告的原因。
thomasrutter 2014年

3
smem是我需要的。通过在每次启动新流程实例时使用-t来运行它,我可以看到每个实例消耗的内存。对于chrome:smem -t -P'/ opt / google /
chrome'– xtian

我很难找到smem文档。默认情况下,它以字节,千字节或兆字节输出吗?
ZN13

4
TL; DR:USS =如果进程被杀死,将释放的物理内存量,PSS =如果没有现有进程将被杀死,该进程从系统需要的物理内存量,RSS =可被进程访问的物理内存量此过程(但不总是独占访问)。
Mikko Rantalainen '18

95
ps -eo size,pid,user,command --sort -size | \
    awk '{ hr=$1/1024 ; printf("%13.2f Mb ",hr) } { for ( x=4 ; x<=NF ; x++ ) { printf("%s ",$x) } print "" }' |\
    cut -d "" -f2 | cut -d "-" -f1

以root用户身份使用它,您可以清楚地了解每个进程的内存使用情况。

输出示例:

     0.00 Mb COMMAND 
  1288.57 Mb /usr/lib/firefox
   821.68 Mb /usr/lib/chromium/chromium 
   762.82 Mb /usr/lib/chromium/chromium 
   588.36 Mb /usr/sbin/mysqld 
   547.55 Mb /usr/lib/chromium/chromium 
   523.92 Mb /usr/lib/tracker/tracker
   476.59 Mb /usr/lib/chromium/chromium 
   446.41 Mb /usr/bin/gnome
   421.62 Mb /usr/sbin/libvirtd 
   405.11 Mb /usr/lib/chromium/chromium 
   302.60 Mb /usr/lib/chromium/chromium 
   291.46 Mb /usr/lib/chromium/chromium 
   284.56 Mb /usr/lib/chromium/chromium 
   238.93 Mb /usr/lib/tracker/tracker
   223.21 Mb /usr/lib/chromium/chromium 
   197.99 Mb /usr/lib/chromium/chromium 
   194.07 Mb conky 
   191.92 Mb /usr/lib/chromium/chromium 
   190.72 Mb /usr/bin/mongod 
   169.06 Mb /usr/lib/chromium/chromium 
   155.11 Mb /usr/bin/gnome
   136.02 Mb /usr/lib/chromium/chromium 
   125.98 Mb /usr/lib/chromium/chromium 
   103.98 Mb /usr/lib/chromium/chromium 
    93.22 Mb /usr/lib/tracker/tracker
    89.21 Mb /usr/lib/gnome
    80.61 Mb /usr/bin/gnome
    77.73 Mb /usr/lib/evolution/evolution
    76.09 Mb /usr/lib/evolution/evolution
    72.21 Mb /usr/lib/gnome
    69.40 Mb /usr/lib/evolution/evolution
    68.84 Mb nautilus
    68.08 Mb zeitgeist
    60.97 Mb /usr/lib/tracker/tracker
    59.65 Mb /usr/lib/evolution/evolution
    57.68 Mb apt
    55.23 Mb /usr/lib/gnome
    53.61 Mb /usr/lib/evolution/evolution
    53.07 Mb /usr/lib/gnome
    52.83 Mb /usr/lib/gnome
    51.02 Mb /usr/lib/udisks2/udisksd 
    50.77 Mb /usr/lib/evolution/evolution
    50.53 Mb /usr/lib/gnome
    50.45 Mb /usr/lib/gvfs/gvfs
    50.36 Mb /usr/lib/packagekit/packagekitd 
    50.14 Mb /usr/lib/gvfs/gvfs
    48.95 Mb /usr/bin/Xwayland :1024 
    46.21 Mb /usr/bin/gnome
    42.43 Mb /usr/bin/zeitgeist
    42.29 Mb /usr/lib/gnome
    41.97 Mb /usr/lib/gnome
    41.64 Mb /usr/lib/gvfs/gvfsd
    41.63 Mb /usr/lib/gvfs/gvfsd
    41.55 Mb /usr/lib/gvfs/gvfsd
    41.48 Mb /usr/lib/gvfs/gvfsd
    39.87 Mb /usr/bin/python /usr/bin/chrome
    37.45 Mb /usr/lib/xorg/Xorg vt2 
    36.62 Mb /usr/sbin/NetworkManager 
    35.63 Mb /usr/lib/caribou/caribou 
    34.79 Mb /usr/lib/tracker/tracker
    33.88 Mb /usr/sbin/ModemManager 
    33.77 Mb /usr/lib/gnome
    33.61 Mb /usr/lib/upower/upowerd 
    33.53 Mb /usr/sbin/gdm3 
    33.37 Mb /usr/lib/gvfs/gvfsd
    33.36 Mb /usr/lib/gvfs/gvfs
    33.23 Mb /usr/lib/gvfs/gvfs
    33.15 Mb /usr/lib/at
    33.15 Mb /usr/lib/at
    30.03 Mb /usr/lib/colord/colord 
    29.62 Mb /usr/lib/apt/methods/https 
    28.06 Mb /usr/lib/zeitgeist/zeitgeist
    27.29 Mb /usr/lib/policykit
    25.55 Mb /usr/lib/gvfs/gvfs
    25.55 Mb /usr/lib/gvfs/gvfs
    25.23 Mb /usr/lib/accountsservice/accounts
    25.18 Mb /usr/lib/gvfs/gvfsd 
    25.15 Mb /usr/lib/gvfs/gvfs
    25.15 Mb /usr/lib/gvfs/gvfs
    25.12 Mb /usr/lib/gvfs/gvfs
    25.10 Mb /usr/lib/gnome
    25.10 Mb /usr/lib/gnome
    25.07 Mb /usr/lib/gvfs/gvfsd 
    24.99 Mb /usr/lib/gvfs/gvfs
    23.26 Mb /usr/lib/chromium/chromium 
    22.09 Mb /usr/bin/pulseaudio 
    19.01 Mb /usr/bin/pulseaudio 
    18.62 Mb (sd
    18.46 Mb (sd
    18.30 Mb /sbin/init 
    18.17 Mb /usr/sbin/rsyslogd 
    17.50 Mb gdm
    17.42 Mb gdm
    17.09 Mb /usr/lib/dconf/dconf
    17.09 Mb /usr/lib/at
    17.06 Mb /usr/lib/gvfs/gvfsd
    16.98 Mb /usr/lib/at
    16.91 Mb /usr/lib/gdm3/gdm
    16.86 Mb /usr/lib/gvfs/gvfsd
    16.86 Mb /usr/lib/gdm3/gdm
    16.85 Mb /usr/lib/dconf/dconf
    16.85 Mb /usr/lib/dconf/dconf
    16.73 Mb /usr/lib/rtkit/rtkit
    16.69 Mb /lib/systemd/systemd
    13.13 Mb /usr/lib/chromium/chromium 
    13.13 Mb /usr/lib/chromium/chromium 
    10.92 Mb anydesk 
     8.54 Mb /sbin/lvmetad 
     7.43 Mb /usr/sbin/apache2 
     6.82 Mb /usr/sbin/apache2 
     6.77 Mb /usr/sbin/apache2 
     6.73 Mb /usr/sbin/apache2 
     6.66 Mb /usr/sbin/apache2 
     6.64 Mb /usr/sbin/apache2 
     6.63 Mb /usr/sbin/apache2 
     6.62 Mb /usr/sbin/apache2 
     6.51 Mb /usr/sbin/apache2 
     6.25 Mb /usr/sbin/apache2 
     6.22 Mb /usr/sbin/apache2 
     3.92 Mb bash 
     3.14 Mb bash 
     2.97 Mb bash 
     2.95 Mb bash 
     2.93 Mb bash 
     2.91 Mb bash 
     2.86 Mb bash 
     2.86 Mb bash 
     2.86 Mb bash 
     2.84 Mb bash 
     2.84 Mb bash 
     2.45 Mb /lib/systemd/systemd
     2.30 Mb (sd
     2.28 Mb /usr/bin/dbus
     1.84 Mb /usr/bin/dbus
     1.46 Mb ps 
     1.21 Mb openvpn hackthebox.ovpn 
     1.16 Mb /sbin/dhclient 
     1.16 Mb /sbin/dhclient 
     1.09 Mb /lib/systemd/systemd 
     0.98 Mb /sbin/mount.ntfs /dev/sda3 /media/n0bit4/Data 
     0.97 Mb /lib/systemd/systemd 
     0.96 Mb /lib/systemd/systemd 
     0.89 Mb /usr/sbin/smartd 
     0.77 Mb /usr/bin/dbus
     0.76 Mb su 
     0.76 Mb su 
     0.76 Mb su 
     0.76 Mb su 
     0.76 Mb su 
     0.76 Mb su 
     0.75 Mb sudo su 
     0.75 Mb sudo su 
     0.75 Mb sudo su 
     0.75 Mb sudo su 
     0.75 Mb sudo su 
     0.75 Mb sudo su 
     0.74 Mb /usr/bin/dbus
     0.71 Mb /usr/lib/apt/methods/http 
     0.68 Mb /bin/bash /usr/bin/mysqld_safe 
     0.68 Mb /sbin/wpa_supplicant 
     0.66 Mb /usr/bin/dbus
     0.61 Mb /lib/systemd/systemd
     0.54 Mb /usr/bin/dbus
     0.46 Mb /usr/sbin/cron 
     0.45 Mb /usr/sbin/irqbalance 
     0.43 Mb logger 
     0.41 Mb awk { hr=$1/1024 ; printf("%13.2f Mb ",hr) } { for ( x=4 ; x<=NF ; x++ ) { printf("%s ",$x) } print "" } 
     0.40 Mb /usr/bin/ssh
     0.34 Mb /usr/lib/chromium/chrome
     0.32 Mb cut 
     0.32 Mb cut 
     0.00 Mb [kthreadd] 
     0.00 Mb [ksoftirqd/0] 
     0.00 Mb [kworker/0:0H] 
     0.00 Mb [rcu_sched] 
     0.00 Mb [rcu_bh] 
     0.00 Mb [migration/0] 
     0.00 Mb [lru
     0.00 Mb [watchdog/0] 
     0.00 Mb [cpuhp/0] 
     0.00 Mb [cpuhp/1] 
     0.00 Mb [watchdog/1] 
     0.00 Mb [migration/1] 
     0.00 Mb [ksoftirqd/1] 
     0.00 Mb [kworker/1:0H] 
     0.00 Mb [cpuhp/2] 
     0.00 Mb [watchdog/2] 
     0.00 Mb [migration/2] 
     0.00 Mb [ksoftirqd/2] 
     0.00 Mb [kworker/2:0H] 
     0.00 Mb [cpuhp/3] 
     0.00 Mb [watchdog/3] 
     0.00 Mb [migration/3] 
     0.00 Mb [ksoftirqd/3] 
     0.00 Mb [kworker/3:0H] 
     0.00 Mb [kdevtmpfs] 
     0.00 Mb [netns] 
     0.00 Mb [khungtaskd] 
     0.00 Mb [oom_reaper] 
     0.00 Mb [writeback] 
     0.00 Mb [kcompactd0] 
     0.00 Mb [ksmd] 
     0.00 Mb [khugepaged] 
     0.00 Mb [crypto] 
     0.00 Mb [kintegrityd] 
     0.00 Mb [bioset] 
     0.00 Mb [kblockd] 
     0.00 Mb [devfreq_wq] 
     0.00 Mb [watchdogd] 
     0.00 Mb [kswapd0] 
     0.00 Mb [vmstat] 
     0.00 Mb [kthrotld] 
     0.00 Mb [ipv6_addrconf] 
     0.00 Mb [acpi_thermal_pm] 
     0.00 Mb [ata_sff] 
     0.00 Mb [scsi_eh_0] 
     0.00 Mb [scsi_tmf_0] 
     0.00 Mb [scsi_eh_1] 
     0.00 Mb [scsi_tmf_1] 
     0.00 Mb [scsi_eh_2] 
     0.00 Mb [scsi_tmf_2] 
     0.00 Mb [scsi_eh_3] 
     0.00 Mb [scsi_tmf_3] 
     0.00 Mb [scsi_eh_4] 
     0.00 Mb [scsi_tmf_4] 
     0.00 Mb [scsi_eh_5] 
     0.00 Mb [scsi_tmf_5] 
     0.00 Mb [bioset] 
     0.00 Mb [kworker/1:1H] 
     0.00 Mb [kworker/3:1H] 
     0.00 Mb [kworker/0:1H] 
     0.00 Mb [kdmflush] 
     0.00 Mb [bioset] 
     0.00 Mb [kdmflush] 
     0.00 Mb [bioset] 
     0.00 Mb [jbd2/sda5
     0.00 Mb [ext4
     0.00 Mb [kworker/2:1H] 
     0.00 Mb [kauditd] 
     0.00 Mb [bioset] 
     0.00 Mb [drbd
     0.00 Mb [irq/27
     0.00 Mb [i915/signal:0] 
     0.00 Mb [i915/signal:1] 
     0.00 Mb [i915/signal:2] 
     0.00 Mb [ttm_swap] 
     0.00 Mb [cfg80211] 
     0.00 Mb [kworker/u17:0] 
     0.00 Mb [hci0] 
     0.00 Mb [hci0] 
     0.00 Mb [kworker/u17:1] 
     0.00 Mb [iprt
     0.00 Mb [iprt
     0.00 Mb [kworker/1:0] 
     0.00 Mb [kworker/3:0] 
     0.00 Mb [kworker/0:0] 
     0.00 Mb [kworker/2:0] 
     0.00 Mb [kworker/u16:0] 
     0.00 Mb [kworker/u16:2] 
     0.00 Mb [kworker/3:2] 
     0.00 Mb [kworker/2:1] 
     0.00 Mb [kworker/1:2] 
     0.00 Mb [kworker/0:2] 
     0.00 Mb [kworker/2:2] 
     0.00 Mb [kworker/0:1] 
     0.00 Mb [scsi_eh_6] 
     0.00 Mb [scsi_tmf_6] 
     0.00 Mb [usb
     0.00 Mb [bioset] 
     0.00 Mb [kworker/3:1] 
     0.00 Mb [kworker/u16:1] 

1
有什么方法可以过滤列表,以便仅使进程使用超过25%的内存(例如30s)?我正在尝试查看使用PHPEclipse调试器时运行的进程,例如Chrome浏览器。
Stephane

该过滤器将很棒
aleix

1
我会尽快将其发布。
Lokendra Singh Rawat

2
大!但是循环应该从x=2开始也要输出pid和user。
鲍里斯·布罗德斯基

70

time

不是猛砸内建time但你可以找到一个which time,例如/usr/bin/time

简单介绍一下ls

$ /usr/bin/time --verbose ls
(...)
Command being timed: "ls"
User time (seconds): 0.00
System time (seconds): 0.00
Percent of CPU this job got: 0%
Elapsed (wall clock) time (h:mm:ss or m:ss): 0:00.00
Average shared text size (kbytes): 0
Average unshared data size (kbytes): 0
Average stack size (kbytes): 0
Average total size (kbytes): 0
Maximum resident set size (kbytes): 2372
Average resident set size (kbytes): 0
Major (requiring I/O) page faults: 1
Minor (reclaiming a frame) page faults: 121
Voluntary context switches: 2
Involuntary context switches: 9
Swaps: 0
File system inputs: 256
File system outputs: 0
Socket messages sent: 0
Socket messages received: 0
Signals delivered: 0
Page size (bytes): 4096
Exit status: 0

我也是。这是我在powercron.eu :)使用配置文件任务的方式
Moonchild

5
brew install gnu-timegtime如果您使用的是macOS,请使用。
Nobu

4
缺点:在过程完成执行之前,不会获得结果。不能用于正在运行的进程的实时监视。
Makesh

/ usr / bin / time -f'%
M'– infomaniac

1
您也可以使用\ time调用它(使用反斜杠以防止使用Shell的内部时间)。
劳尔·萨利纳斯-蒙塔古多

39

这是有关工具和问题的出色摘要:archive.org链接

我会引用它,以便更多开发人员实际阅读它。

如果要分析整个系统的内存使用情况或要彻底分析一个应用程序的内存使用情况(而不仅仅是堆使用情况),请使用exmap。对于整个系统分析,查找具有最高有效使用率的进程,它们在实践中会占用最多的内存,查找具有最高可写使用率的进程,它们会创建最多的数据(因此可能会泄漏数据,或者数据使用效率非常低)。选择此类应用程序并在第二个列表视图中分析其映射。有关更多详细信息,请参见exmap部分。还可以使用xrestop检查X资源的高使用率,尤其是在X服务器的进程占用大量内存的情况下。有关详细信息,请参见xrestop部分。

如果要检测泄漏,请使用valgrindkmtrace

如果要分析应用程序的堆(malloc等)使用情况,请在memprof中运行它或使用kmtrace运行它,分析应用程序并在函数调用树中搜索最大的分配。请参阅他们的章节以获取更多详细信息。


28

除了您的答案中列出的解决方案之外,您还可以使用Linux命令“ top”;它提供了正在运行的系统的动态实时视图,以百分比的形式给出了整个系统以及每个程序的CPU和内存使用情况:

top

通过程序pid进行过滤:

top -p <PID>

按程序名称过滤:

top | grep <PROCESS NAME>

“顶部”还提供了一些字段,例如:

VIRT-虚拟映像(kb):任务使用的虚拟内存总量

RES-驻留大小(kb):任务已使用的未交换物理内存;RES =代码+数据。

DATA-数据+堆栈大小(kb):专用于可执行代码以外的物理内存量,也称为“数据驻留集”大小或DRS。

SHR-共享内存大小(kb):任务使用的共享内存量。它只是反映了可能与其他进程共享的内存。

参考这里


20

这个问题没有一个答案,因为您无法精确指出一个进程使用的内存量。Linux下的大多数进程都使用共享库。例如,假设您要计算“ ls”进程的内存使用情况。您是否只计算可执行文件“ ls”使用的内存(如果可以隔离的话)?libc呢?还是运行“ ls”所需的所有其他这些库?

linux-gate.so.1 =>  (0x00ccb000)
librt.so.1 => /lib/librt.so.1 (0x06bc7000)
libacl.so.1 => /lib/libacl.so.1 (0x00230000)
libselinux.so.1 => /lib/libselinux.so.1 (0x00162000)
libc.so.6 => /lib/libc.so.6 (0x00b40000)
libpthread.so.0 => /lib/libpthread.so.0 (0x00cb4000)
/lib/ld-linux.so.2 (0x00b1d000)
libattr.so.1 => /lib/libattr.so.1 (0x00229000)
libdl.so.2 => /lib/libdl.so.2 (0x00cae000)
libsepol.so.1 => /lib/libsepol.so.1 (0x0011a000)

您可能会争辩说它们由其他进程共享,但是如果不加载“ ls”,则无法在系统上运行它们。

同样,如果您需要知道一个进程需要多少内存才能进行容量规划,则必须计算该进程的每个附加副本要使用多少内存。我认为/ proc / PID / status可能会一次给您足够的内存使用信息。另一方面,valgrind将在程序的整个生命周期内为您提供更好的内存使用情况配置文件


我试图找到一个进程正在VM上占用多少内存,并希望使用它来设置kubernetes中的内存限制,我同意这个答案,因此将使用pmap
Deepak Deore

16

如果您的代码是C或C ++,则可以使用getrusage()它返回有关进程的内存和时间使用情况的各种统计信息。

但是,并非所有平台都支持此功能,并且会为内存使用选项返回0值。

相反,您可以查看在中创建的虚拟文件/proc/[pid]/statm(其中的[pid]已替换为您的进程ID。您可以从中获得此文件getpid())。

该文件看起来像是带有7个整数的文本文件。您可能对该文件中的第一个(所有内存使用)和第六个(数据内存使用)数字最感兴趣。


请注意,并非所有平台都支持此功能。
CashCow

根据Linux手册页(linux.die.net/man/2/getrusage),getrusageSVr4、4.3BSD和POSIX.1-2001规范的一部分(请注意POSIX仅指定utime和stime字段。)不会指望它能在非UNIX平台上运行(除非可能是通过Cygwin之类的环境为其他平台提供UNIX功能。)
David C.

@DavidC。OP正在询问有关Linux的信息。
亚历克西斯·威尔克

@CashCow,您的意思是getpid()因为我不知道getprocessid()Linux下C / C ++ 中的功能。
亚历克西斯·威尔克

12

Valgrind可以显示详细信息,但大大降低目标应用程序的速度,并且在大多数情况下会改变应用程序的行为。
Exmap是我不知道的东西,但是似乎您需要一个内核模块来获取信息,这可能是一个障碍。

我假设每个人都想知道WRT的“内存使用情况”如下...
在Linux中,单个进程可能使用的物理内存量可以大致分为以下几类。

  • 马匿名映射的内存

    • .p私人
      • .d脏== malloc /映射的堆和堆栈分配与写入内存
      • .c clean == malloc /映射的堆和堆栈内存一旦分配,写入,然后释放但尚未回收
    • .s分享了
      • .ddirty == malloc / mmaped堆可以写时复制并在进程之间共享(已编辑)
      • .c clean == malloc / mmaped堆可以写时复制并在进程之间共享(已编辑)
  • 锰命名映射存储器

    • .p私人
      • .d脏==文件映射的写入内存专用
      • .c clean ==映射的程序/库文本专用映射
    • .s分享了
      • .d脏==文件映射了共享的写入内存
      • .c clean ==映射库文本共享映射

Android中包含的名为showmap的实用程序非常有用

virtual                    shared   shared   private  private
size     RSS      PSS      clean    dirty    clean    dirty    object
-------- -------- -------- -------- -------- -------- -------- ------------------------------
       4        0        0        0        0        0        0 0:00 0                  [vsyscall]
       4        4        0        4        0        0        0                         [vdso]
      88       28       28        0        0        4       24                         [stack]
      12       12       12        0        0        0       12 7909                    /lib/ld-2.11.1.so
      12        4        4        0        0        0        4 89529                   /usr/lib/locale/en_US.utf8/LC_IDENTIFICATION
      28        0        0        0        0        0        0 86661                   /usr/lib/gconv/gconv-modules.cache
       4        0        0        0        0        0        0 87660                   /usr/lib/locale/en_US.utf8/LC_MEASUREMENT
       4        0        0        0        0        0        0 89528                   /usr/lib/locale/en_US.utf8/LC_TELEPHONE
       4        0        0        0        0        0        0 89527                   /usr/lib/locale/en_US.utf8/LC_ADDRESS
       4        0        0        0        0        0        0 87717                   /usr/lib/locale/en_US.utf8/LC_NAME
       4        0        0        0        0        0        0 87873                   /usr/lib/locale/en_US.utf8/LC_PAPER
       4        0        0        0        0        0        0 13879                   /usr/lib/locale/en_US.utf8/LC_MESSAGES/SYS_LC_MESSAGES
       4        0        0        0        0        0        0 89526                   /usr/lib/locale/en_US.utf8/LC_MONETARY
       4        0        0        0        0        0        0 89525                   /usr/lib/locale/en_US.utf8/LC_TIME
       4        0        0        0        0        0        0 11378                   /usr/lib/locale/en_US.utf8/LC_NUMERIC
    1156        8        8        0        0        4        4 11372                   /usr/lib/locale/en_US.utf8/LC_COLLATE
     252        0        0        0        0        0        0 11321                   /usr/lib/locale/en_US.utf8/LC_CTYPE
     128       52        1       52        0        0        0 7909                    /lib/ld-2.11.1.so
    2316       32       11       24        0        0        8 7986                    /lib/libncurses.so.5.7
    2064        8        4        4        0        0        4 7947                    /lib/libdl-2.11.1.so
    3596      472       46      440        0        4       28 7933                    /lib/libc-2.11.1.so
    2084        4        0        4        0        0        0 7995                    /lib/libnss_compat-2.11.1.so
    2152        4        0        4        0        0        0 7993                    /lib/libnsl-2.11.1.so
    2092        0        0        0        0        0        0 8009                    /lib/libnss_nis-2.11.1.so
    2100        0        0        0        0        0        0 7999                    /lib/libnss_files-2.11.1.so
    3752     2736     2736        0        0      864     1872                         [heap]
      24       24       24        0        0        0       24 [anon]
     916      616      131      584        0        0       32                         /bin/bash
-------- -------- -------- -------- -------- -------- -------- ------------------------------
   22816     4004     3005     1116        0      876     2012 TOTAL

10

可以尝试以下三种方法:

  1. ps aux --sort pmem
    它将输出排序为%MEM
  2. ps aux | awk '{print $2, $4, $11}' | sort -k2r | head -n 15
    它使用管道进行排序。
  3. top -a
    它开始按以下顺序排序 %MEM

(从这里提取)


2
top可能其他人不能准确表示该进程实际使用的内存。例如,我有64GiB的RAM,我有10个postgres进程,每个进程报告16GiB RES和25%的MEM。当然,他们不能全都使用25%...每个人也都有15GiB SHR,看来他们正在共享。
sudo

8
#!/bin/ksh
#
# Returns total memory used by process $1 in kb.
#
# See /proc/NNNN/smaps if you want to do something
# more interesting.
#

IFS=$'\n'

for line in $(</proc/$1/smaps)
do
   [[ $line =~ ^Size:\s+(\S+) ]] && ((kb += ${.sh.match[1]}))
done

print $kb

5
ksh是标准外壳程序。对于桌面用户或出于简约目的,默认情况下可能未将其安装在Linux发行版上,但是在几乎所有的unix- / linux操作系统中,它只是一个命令。(即在所有BSD,所有真实UNIX,RHEL,SLES,Debian,Ubuntu,OSX上)
Florian Heigl

默认情况下,只有root用户可以访问此文件。
德米特里·金茨堡

下面只是上述改写成sed | awk:在Busybox的v1.23.2作品 sed -n 's/^Size:\s\+\(\S\+\) .*/\1/p' /proc/$1/smaps | awk '{s+=$1} END {print s}'
扬Sáreník

1
@Catskul-POSIX标准将其标准shell指定为Korn shell(Bourne shell的增强版本)的严格子集。
ceph3us

8

我使用的htop; 这是一个非常好的控制台程序,类似于Windows Task Manager。


我曾经使用过,htop并且比top更好,但是它仍然会向您显示来自不同应用程序的所有线程,而没有将它们分组,从而使它几乎和top一样无用。
sorin

1
$ htop -p $(pgrep <您的进程名称> | xargs | tr''',')
AAAfarmclub

6

如果该进程没有占用过多的内存(或者因为您期望这种情况,或者某些其他命令给出了此初始指示),并且该进程可以承受短时间的停止,则可以尝试使用gcore命令。

gcore <pid>

检查生成的核心文件的大小,可以很好地了解特定进程正在使用多少内存。

如果进程使用数百兆或演出,这将不能很好地工作,因为根据I / O性能,创建核心代可能需要几秒钟或几分钟。在核心创建过程中,该过程将停止(或“冻结”)以防止内存更改。所以要小心

还要确保生成内核的安装点具有足够的磁盘空间,并且系统不会对在该特定目录中创建的内核文件产生负面影响。


6

我正在使用Arch Linux,有一个很棒的软件包叫做 ps_mem

ps_mem -p <pid>

示例输出

$ ps_mem -S -p $(pgrep firefox)

Private   +   Shared  =  RAM used   Swap used   Program

355.0 MiB +  38.7 MiB = 393.7 MiB    35.9 MiB   firefox
---------------------------------------------
                        393.7 MiB    35.9 MiB
=============================================

5

下面的命令行将为您提供Linux机器上运行的各种进程使用的总内存,以MB为单位

ps -eo size,pid,user,command --sort -size | awk '{ hr=$1/1024 ; printf("%13.2f Mb ",hr) } { for ( x=4 ; x<=NF ; x++ ) { printf("%s ",$x) } print "" }' | awk '{total=total + $1} END {print total}'

5

一个更好的“现实世界”用法测试是打开应用程序,然后运行vmstat -s并检查“活动内存”统计信息。关闭应用程序,等待几秒钟,然后vmstat -s再次运行。但是,该应用程序显然正在使用大量活动内存。


3
怎么会比ps更好呢?它带有ps的所有限制,甚至更加不准确...
Lester Cheung

一个典型的Unix系统始终具有许多启动和结束的过程。您无法预测您的可用RAM。
劳尔·萨利纳斯,蒙特阿古

4

获取valgrind。给它运行程序,它将告诉您很多有关其内存使用情况的信息。

这仅适用于程序运行一段时间并停止的情况。我不知道valgrind是否可以掌握已经在运行的进程,还是不应该停止诸如守护程序之类的进程。


不,不可能将valgrind“附加”到正在运行的进程。那是设计使然。
Dima Tisnek

3

编辑:仅当内存消耗增加时,此方法才能100%有效

如果要按给定进程(或一组经过处理的共享通用名,例如)监视内存使用情况google-chrome,则可以使用我的bash脚本:

while true; do ps aux | awk ‚{print $5, $11}’ | grep chrome | sort -n > /tmp/a.txt; sleep 1; diff /tmp/{b,a}.txt; mv /tmp/{a,b}.txt; done;

这将不断寻找更改并进行打印。

在此处输入图片说明


3

如果您想要比使用Valgrind进行性能分析更快的速度并且您的内核更旧并且不能使用smaps,则带有ps选项的选项可以显示进程的驻留集(带有ps -o rss,command),可以使您快速而合理_aproximation_地了解实际数量使用非交换内存。


3

我建议您在上面使用。您可以在此页面上找到有关它的所有信息。它能够为您的流程提供所有必要的KPI,并且还可以捕获到文件中。


2
要显示PSIZE [“此进程(或用户)的相应内存大小”,请在顶部启动atop -R。要显示每个用户的摘要推送p,请按顶部的“ M”按内存使用情况进行排序。这与smem类似。
Markus Strauss


1

再次投票 在这里,但我想补充一点,您可以使用Alleyoop之类的工具来帮助您解释valgrind生成的结果。

我一直使用这两个工具,并且总是有精益,无泄漏的代码来自豪地展示它;)


1

尽管这个问题似乎与检查当前正在运行的进程有关,但我还是想从头到尾查看应用程序使用的峰值内存。除了valgrind之外,您还可以使用tstime,这要简单得多。它测量“高水位”内存使用情况(RSS和虚拟)。从这个答案


大多数应用程序-即那些使用malloc()和类似malloc的内存库的应用程序-直到终止后才将页面返回到OS。因此,使用PS(或其他任何未挖掘到进程堆中的工具)看到的数量将是最高水平。
David C.

0

基于对相关问题的回答

您可以使用SNMP获取网络中特定设备中进程的内存和cpu使用情况:)

要求:

  • 运行该进程的设备应已安装并正在运行snmp
  • 应该将snmp配置为接受您将在下面运行脚本的位置的请求(可以在snmpd.conf中进行配置)
  • 您应该知道要监视的进程的进程ID(pid)

笔记:

  • HOST-RESOURCES-MIB :: hrSWRunPerfCPU是此进程消耗的系统总CPU资源的秒数。请注意,在多处理器系统上,此值可能会在实际(挂钟)时间的1厘秒中增加1厘秒以上。

  • HOST-RESOURCES-MIB :: hrSWRunPerfMem是分配给该进程的实际系统内存的总量。

**

流程监控脚本:

**

echo "IP: "
read ip
echo "specfiy pid: "
read pid
echo "interval in seconds:"
read interval

while [ 1 ]
do
    date
    snmpget -v2c -c public $ip HOST-RESOURCES-MIB::hrSWRunPerfCPU.$pid
    snmpget -v2c -c public $ip HOST-RESOURCES-MIB::hrSWRunPerfMem.$pid
    sleep $interval;
done

0

/ prox / xxx / numa_maps在此处提供了一些信息:N0 = ??? N1 = ???。但是此结果可能会低于实际结果,因为它只计算已被触摸的那些。


-1

使用ubuntu中提供的内置“ 系统监视器 ” GUI工具


1
至少从16.04开始,效果很好。不过,这非常像top,所使用的内存不是非常精确...
Alexis Wilke
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.