在Linux中,如何判断正在使用多少内存进程?


73

我认为我的LAMP应用程序中可能发生内存泄漏(内存被耗尽,交换开始被使用,等等)。如果我可以看到各个进程使用了​​多少内存,则可以帮助我解决问题。有没有办法让我在* nix中查看此信息?

Answers:


96

获得正确的内存使用率比人们想象的要难。我能找到的最好方法

echo 0 $(awk '/TYPE/ {print "+", $2}' /proc/`pidof PROCESS`/smaps) | bc

其中“ PROCESS”是要检查的过程的名称,而“ TYPE”是以下之一:

  • Rss:常驻内存使用情况,该进程使用的所有内存,包括该进程与其他进程共享的所有内存。它不包括掉期;
  • Shared:该进程与其他进程共享的内存;
  • Private:此过程使用的私有内存,您可以在此处查找内存泄漏;
  • Swap:交换进程使用的内存;
  • Pss:比例设置大小,良好的整体内存指示器。它是为共享而调整的Rss:如果某个进程在其他10个进程之间具有1MiB专用和20MiB共享,则Pss为1 + 20/10 = 3MiB

其他有效值是Size(即虚拟大小,几乎没有意义)和Referenced(当前标记为引用或访问的内存量)。

您可以使用watch或其他bash-script-fu来监视要监视的进程的那些值。

有关更多信息smapshttp : //www.kernel.org/doc/Documentation/filesystems/proc.txt


这真是太棒了,但是看起来它返回的是以KB为单位的内存(无论如何对于Rss和Private)。您知道如何获取字节存储空间吗?
马特·菲利普斯

5
时代变长了,可能不再相关了,但是:实际的内存分配始终是物理页面大小的倍数,在现代系统上,它始终是1024字节的小数倍。因此,只需将KB的大小乘以1024即可得到字节;没有舍入错误。(内核几乎没有感染过iB疾病:除非有明确的相反证据,否则假设K = 1024而不是1000。)
zwol 2013年

对于这样的场景,gist.github.com / 9bbd0ce953143b67c038消耗的“总”内存是多少
ylluminate 2014年

1
您可以只用awk做cat + grep + awk + ​​sed:echo 0 $(sudo awk '/TYPE/ {print "+", $2}' /proc/PID/smaps) | bc
Bryan

2
为什么不将其全部awk传递而不是传递给bcawk 'BEGIN { used=0 }; /TYPE/ { used += $2 } END { print used }' /proc/PID/smaps将为您提供KB大小。
Glen Solsberry

59

我不知道为什么答案看起来如此复杂...这样做似乎很简单ps

mem()
{                                                                                                      
    ps -eo rss,pid,euser,args:100 --sort %mem | grep -v grep | grep -i $@ | awk '{printf $1/1024 "MB"; $1=""; print }'
}

用法示例:

$ mem mysql
0.511719MB 781 root /bin/sh /usr/bin/mysqld_safe
0.511719MB 1124 root logger -t mysqld -p daemon.error
2.53516MB 1123 mysql /usr/sbin/mysqld --basedir=/usr --datadir=/var/lib/mysql --plugin-dir=/usr/lib/mysql/plugin --user=mysql --pid-file=/var/run/mysqld/mysqld.pid --socket=/var/run/mysqld/mysqld.sock --port=3306

1
很棒的功能。将此内容添加到我的.zshrc
watzon

方便的功能。值得注意的是,rss用于计算的列(Resident Set Size)包含共享库中的内存,因此将数字丢弃。就我而言,进程使用的内存比系统可用的内存更多。
AlexT

这就是答案,不知道为什么其他人被标记为正确,我从中得到的只是结果“ 0”,这正是我所需要的...谢谢
THESorcerer

1
这是正确的答案,可以在Linux上完美运行
LnxSlck

37

使用ps查找应用程序的进程ID,然后使用top -p1010(将1010替换为实际进程ID)。RES列是已使用的物理内存,VIRT列是已使用的虚拟内存-包括库和交换的内存。

可以使用“ man top”找到更多信息


1
到我可以执行top -pXXXX时,该过程已经完成。所以,我什么也没得到。有什么建议吗?
StackOverflowNewbie

3
关于“ VIRT”:对于几乎所有实际目的,虚拟映像的大小都不能告诉您-几乎每个linux系统都配置为允许内存过量使用,并且许多应用程序实际上都进行了过量使用。
Gunther Piez

这是一个衬套,可让您指定进程的名称(假设只有一个与该名称匹配的进程):top -p`ps -ef | grep -i $NAME_OF_PROCESS | grep -v grep | gawk '{print $2}'`
Trevor Boyd Smith

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

17

首先获取pid:

ps ax | grep [process name]

接着:

top -p PID

您可以同时观看各种过程:

top -p PID1 -p PID2 


7

更优雅的方法:

echo "Memory usage for PID <>:"; for mem in {Private,Rss,Shared,Swap,Pss};do grep $mem /proc/<pid>/smaps | awk -v mem_type="$mem" '{i=i+$2} END {print mem_type,"memory usage:"i}' ;done

6

使用tophtop并注意“ RES”(驻留内存大小)列。


我看到了RES,但我认为我不需要。我用过的Mem和用过的Swap持续增长。我需要知道是什么使这些上升。有想法吗?
StackOverflowNewbie

常驻内存是您的进程使用的内存。如果尽管总内存使用量增加了,但似乎所有进程都没有使用太多内存,则该内存只能由内核使用。尝试在RES列之后排序。还有一点,当您有大量磁盘IO时,交换性可能会太高。
Gunther Piez

htop -t在树视图中显示进程,因此您可以在树视图中查看RES内存。
oml

6

谢谢。我用它来创建这个简单的bash脚本,该脚本可用于监视进程及其内存使用情况:

$ watch watchmypid.sh

#!/bin/bash
#

PROCESSNAME=changethistoyourprocessname
MYPID=`pidof $PROCESSNAME`

echo "=======";
echo PID:$MYPID
echo "--------"
Rss=`echo 0 $(cat /proc/$MYPID/smaps  | grep Rss | awk '{print $2}' | sed 's#^#+#') | bc;`
Shared=`echo 0 $(cat /proc/$MYPID/smaps  | grep Shared | awk '{print $2}' | sed 's#^#+#') | bc;`
Private=`echo 0 $(cat /proc/$MYPID/smaps  | grep Private | awk '{print $2}' | sed 's#^#+#') | bc;`
Swap=`echo 0 $(cat /proc/$MYPID/smaps  | grep Swap | awk '{print $2}' | sed 's#^#+#') | bc;`
Pss=`echo 0 $(cat /proc/$MYPID/smaps  | grep Pss | awk '{print $2}' | sed 's#^#+#') | bc;`

Mem=`echo "$Rss + $Shared + $Private + $Swap + $Pss"|bc -l`

echo "Rss     " $Rss
echo "Shared  " $Shared
echo "Private " $Private
echo "Swap    " $Swap
echo "Pss     " $Pss
echo "=================";
echo "Mem     " $Mem
echo "=================";

可能是因为脚本通过smaps文件经过5次传递来计算数据。一次进行awk解析和计算应该相当容易。
TimothéeGroleau

@TimothéeGroleau同意awk的性能,无论如何,脚本看起来很酷,而且有人可以从中学到一些东西。也许Paul Rubenstein想更新他们的剧本:D。谢谢。
m3nda

6

如果您没有当前或长期运行的流程需要跟踪,可以使用/usr/bin/time

这与Bash不同time(如您所见)。

例如

# /usr/bin/time -f "%M" echo

2028

这是“进程在其生存期内的最大驻留集大小,以千字节为单位”(从手册页中引用)。即与RES中的相同top等人。

您可以从中得到更多/usr/bin/time

# /usr/bin/time -v echo

Command being timed: "echo"
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): 1988
Average resident set size (kbytes): 0
Major (requiring I/O) page faults: 0
Minor (reclaiming a frame) page faults: 77
Voluntary context switches: 1
Involuntary context switches: 0
Swaps: 0
File system inputs: 0
File system outputs: 0
Socket messages sent: 0
Socket messages received: 0
Signals delivered: 0
Page size (bytes): 4096
Exit status: 0

2
macos / usr / bin / time无法进行此级别的分析,但是自家软件确实通过该gnu-time软件包提供了正确的实用程序。它安装了一个名为的实用程序gtime,它可以满足您的需求。
voxobscuro

4

您想要的工具是ps。要获取有关Java程序正在做什么的信息:

ps -F -C java 

要获取有关http的信息:

ps -F -C httpd

如果您的程序在您有机会运行它们之前已结束,请打开另一个终端并运行:

while true; do ps -F -C myCoolCode ; sleep 0.5s ; done

4

您可以使用pmap+ awk

最有可能的是,我们对以下RSS示例pmap输出的最后一行的第三列(82564)的内存感兴趣。

$ pmap -x <pid>

Address           Kbytes     RSS   Dirty Mode   Mapping

....

00007f9caf3e7000       4       4       4 r----  ld-2.17.so
00007f9caf3e8000       8       8       8 rw---  ld-2.17.so
00007fffe8931000     132      12      12 rw---    [ stack ]
00007fffe89fe000       8       8       0 r-x--    [ anon ]
ffffffffff600000       4       0       0 r-x--    [ anon ]
----------------  ------  ------  ------
total kB          688584   82564    9592

然后使用Awk提取该值。

$ pmap -x <pid> | awk '/total/ { print $4 "K" }'

pmap值以千字节为单位。如果我们希望以兆字节为单位,则可以执行以下操作。

$ pmap -x <pid> | awk '/total/ { print $4 / 1024 "M" }'

2

为什么所有这些复杂的答案都带有各种shell脚本?使用htop,它将自动更改大小,并且您可以选择要显示的信息,并且可以在终端中使用,因此不需要桌面。示例:htop -d8


大多数使用命令行的人都对以编程方式解决它感兴趣。在某些情况下,他们只是想学习如何使用内核而不是预构建过程来解决问题。
犹他州黑海德'16

1

采用

  • ps u`pidof $ TASKS_LIST`ps u -C $ TASK
  • ps xu --sort%mem
  • ps h -o pmem -C $ TASK

例:

ps-of()
{
 ps u `pidof "$@"`
}

$ ps-of firefox
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
const    18464  5.9  9.4 1190224 372496 ?      Sl   11:28   0:33 /usr/lib/firefox/firefox

$ alias ps-mem="ps xu --sort %mem | sed -e :a -e '1p;\$q;N;6,\$D;ba'"
$ ps-mem 
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
const     3656  0.0  0.4 565728 18648 ?        Sl   Nov21   0:56 /usr/bin/python /usr/lib/ubuntuone-client/ubuntuone-syncdaemon
const    11361  0.3  0.5 1054156 20372 ?       Sl   Nov25  43:50 /usr/bin/python /usr/bin/ubuntuone-control-panel-qt
const     3402  0.0  0.5 1415848 23328 ?       Sl   Nov21   1:16 nautilus -n
const     3577  2.3  2.0 1534020 79844 ?       Sl   Nov21 410:02 konsole
const    18464  6.6 12.7 1317832 501580 ?      Sl   11:28   1:34 /usr/lib/firefox/firefox

$ ps h -o pmem -C firefox
12.7
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.