我有一台12G内存的服务器。top的一个片段如下所示:

PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND                                                                                                                                                                                                                                                      
12979 frank  20   0  206m  21m  12m S   11  0.2  26667:24 krfb                                                                                                                                                                                                                                                          
13 root      15  -5     0    0    0 S    1  0.0  36:25.04 ksoftirqd/3                                                                                                                                                                                                                                                   
59 root      15  -5     0    0    0 S    0  0.0   4:53.00 ata/2                                                                                                                                                                                                                                                         
2155 root      20   0  662m  37m 8364 S    0  0.3 338:10.25 Xorg                                                                                                                                                                                                                                                          
4560 frank  20   0  8672 1300  852 R    0  0.0   0:00.03 top                                                                                                                                                                                                                                                           
12981 frank  20   0  987m  27m  15m S    0  0.2  45:10.82 amarok                                                                                                                                                                                                                                                        
24908 frank  20   0 16648  708  548 S    0  0.0   2:08.84 wrapper                                                                                                                                                                                                                                                       
1 root      20   0  8072  608  572 S    0  0.0   0:47.36 init                                                                                                                                                                                                                                                          
2 root      15  -5     0    0    0 S    0  0.0   0:00.00 kthreadd

free -m显示如下:

             total       used       free     shared    buffers     cached
Mem:         12038      11676        362          0        599       9745
-/+ buffers/cache:       1331      10706
Swap:         2204        257       1946

如果我理解正确的话,系统只有362 MB的可用内存。我的问题是:如何知道哪个进程消耗了最多的内存?

作为背景信息,系统正在运行64位的OpenSuse 12。


当前回答

基于gaoithe的回答,我试图使内存单位以兆字节为单位显示,并按内存降序排序,限制为15个条目:

ps - e -orss =, arg游戏= | awk '{打印$ 1 " " $ 2}’| awk的{合计(2美元)+ = 1美元;数(2美元)+ +}结束为tot(我){{打印合计(我),我数[我]}}”|排序- n 15 | | tail - n排序nr | awk的{hr = 1/1024美元;printf (" % 13.2 fm”、人力资源);打印"\t" $2}'

       588.03M  /usr/sbin/apache2
       275.64M  /usr/sbin/mysqld
       138.23M  vim
        97.04M  -bash
        40.96M  ssh
        34.28M  tmux
        17.48M  /opt/digitalocean/bin/do-agent
        13.42M  /lib/systemd/systemd-journald
        10.68M  /lib/systemd/systemd
        10.62M  /usr/bin/redis-server
         8.75M  awk
         7.89M  sshd:
         4.63M  /usr/sbin/sshd
         4.56M  /lib/systemd/systemd-logind
         4.01M  /usr/sbin/rsyslogd

下面是在bash配置文件中使用别名的示例:

    alias topmem="ps -e -orss=,args= |awk '{print \$1 \" \" \$2 }'| awk '{tot[\$2]+=\$1;count[\$2]++} END {for (i in tot) {print tot[i],i,count[i]}}' | sort -n | tail -n 15 | sort -nr | awk '{ hr=\$1/1024; printf(\"%13.2fM\", hr); print \"\t\" \$2 }'"

然后只需在命令行上键入topmem。

其他回答

如何按进程名合计使用的内存:

有时,即使查看最大的单个进程,仍然有许多使用的内存未被考虑。要检查是否有很多相同的小进程使用内存,您可以使用如下命令,使用awk来计算相同名称的进程使用的内存总量:

ps -e -orss=,args= |awk '{print $1 " " $2 }'| awk '{tot[$2]+=$1;count[$2]++} END {for (i in tot) {print tot[i],i,count[i]}}' | sort -n

如输出

9344 docker 1
9948 nginx: 4
22500 /usr/sbin/NetworkManager 1
24704 sleep 69
26436 /usr/sbin/sshd 15
34828 -bash 19
39268 sshd: 10
58384 /bin/su 28
59876 /bin/ksh 29
73408 /usr/bin/python 2
78176 /usr/bin/dockerd 1
134396 /bin/sh 84
5407132 bin/naughty_small_proc 1432
28061916 /usr/local/jdk/bin/java 7

你可以按照以下步骤指定要排序的列:

steps:
* top
* shift + F
* select a column from the list
    e.g. n means sort by memory,
* press enter
* ok

首先,把这句话重复一段时间:“未使用的内存就是浪费的内存”。Linux内核保留了大量的文件元数据和被请求的文件,直到某些看起来更重要的东西将这些数据推出。这就是为什么你可以跑:

find /home -type f -name '*.mp3'
find /home -type f -name '*.aac'

让第二个查找实例以惊人的速度运行。

Linux只留下一点“空闲”内存,以轻松处理内存使用高峰。

其次,您希望找到正在消耗所有内存的进程;在顶部使用M命令按内存使用进行排序。可以忽略VIRT列,它只告诉您分配了多少虚拟内存,而不是进程使用了多少内存。RES报告有多少内存驻留,或当前在ram中(而不是交换到磁盘或尽管被请求,但从未实际分配)。

但是,由于RES将计数,例如/lib/libc.so. so对于几乎每个进程都使用一次6内存,这并不是一个度量进程使用多少内存的好方法。SHR列报告了与其他进程共享了多少内存,但不能保证实际上有另一个进程正在共享——它可能是可共享的,只是没有其他人想要共享。

smem工具旨在帮助用户更好地衡量每个进程应该占用多少内存。它做了一些聪明的工作,找出哪些是真正唯一的,哪些是共享的,并按比例计算共享内存与共享内存的进程。Smem可能会比top更好地帮助你了解你的记忆进展,但top是一个很好的首选工具。

你有这样一个简单的命令:

$ free -h

根据内存使用情况列出和排序进程:

ps -e -orss=,args= | sort -b -k1,1n | pr -TW$COLUMNS