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

How to measure actual memory usage of an application or process?

这个问题在这里有很详细的介绍。

在Linux中,如何度量应用程序或进程的内存使用情况?

从理解Linux上内存使用的博客文章来看,ps不是用于此目的的准确工具。

Why ps is"wrong"

Depending on how you look at it, ps is not reporting the real memory usage of processes. What it is really doing is showing how much real memory each process would take up if it were the only process running. Of course, a typical Linux machine has several dozen processes running at any given time, which means that the VSZ and RSS numbers reported by ps are almost definitely wrong.


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

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

  • 如果页面是共享的,例如由多个线程或使用动态链接库,则可能会产生误导。

如果您真的想知道应用程序实际使用的内存量,您需要在分析器中运行它。例如,valgrind可以让您了解所使用的内存量,更重要的是,还可以了解程序中可能发生的内存泄漏。valgrind的堆分析器工具称为"massif":

Massif is a heap profiler. It performs detailed heap profiling by taking regular snapshots of a program's heap. It produces a graph showing heap usage over time, including information about which parts of the program are responsible for the most memory allocations. The graph is supplemented by a text or HTML file that includes more information for determining where the most memory is being allocated. Massif runs programs about 20x slower than normal.

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

1
valgrind --tool=massif <executable>

massif写入内存使用快照的转储(例如massif.out.12345)。它们提供:(1)内存使用的时间表;(2)对于每个快照,都提供程序内存中分配位置的记录。分析这些文件的一个很好的图形工具是Massif可视化工具。但我发现,Valgrind附带的一个简单的基于文本的工具ms_print已经很有帮助了。

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


尝试pmap命令:

1
sudo pmap -x <process pid>


很难说是肯定的,但这里有两个"接近"的东西可以帮助。

1
$ ps aux

将为您提供虚拟大小(vsz)

您还可以通过访问/proc/$pid/status从/proc文件系统获取详细的统计信息。

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
/proc/19420$ cat status
Name:   firefox
State:  S (sleeping)
Tgid:   19420
Pid:    19420
PPid:   1
TracerPid:  0
Uid:    1000    1000    1000    1000
Gid:    1000    1000    1000    1000
FDSize: 256
Groups: 4 6 20 24 25 29 30 44 46 107 109 115 124 1000
VmPeak:   222956 kB
VmSize:   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
Threads:    8
SigQ:   0/16382
SigPnd: 0000000000000000
ShdPnd: 0000000000000000
SigBlk: 0000000000000000
SigIgn: 0000000020001000
SigCgt: 000000018000442f
CapInh: 0000000000000000
CapPrm: 0000000000000000
CapEff: 0000000000000000
Cpus_allowed:   03
Mems_allowed:   1
voluntary_ctxt_switches:    63422
nonvoluntary_ctxt_switches: 7171


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

1
cat /proc/1234/smaps

它将准确地告诉你当时它使用了多少内存。更重要的是,它将内存划分为私有内存和共享内存,这样您就可以知道您的程序实例使用了多少内存,而不包括程序多个实例之间共享的内存。


没有简单的方法来计算这个。但有些人试图得到一些好的答案:

  • PS-MEM.Py
  • Github的PS Mem.py


使用SMEM,它是计算每个进程的USS和PSS的PS的替代方案。你想要的可能是PSS。

  • USS-唯一设置大小。这是该进程独有的非共享内存量(将其视为唯一内存的u)。它不包括共享内存。因此,这将低估进程使用的内存量,但当您想忽略共享内存时,这将很有帮助。

  • PSS-比例集大小。这就是你想要的。它将唯一内存(uss)加在一起,并将共享内存的一部分除以共享该内存的其他进程的数量。因此,它将为您提供每个进程实际使用的物理内存量的精确表示,共享内存真正表示为共享内存。想象一下P代表物理记忆。

这与PS和其他实用程序报告的RSS的比较方式:

  • rss-常驻集大小。这是每个进程使用的共享内存加上非共享内存的数量。如果任何进程共享内存,这将过度报告实际使用的内存量,因为相同的共享内存将被多次计数-在共享相同内存的其他进程中再次出现。因此,它是相当不可靠的,尤其是当高内存进程有很多分叉时——这在服务器中很常见,比如Apache或PHP(FastCGI/FPM)进程。

注意:SMEM还可以(可选)输出饼图等图形。我觉得你不需要这些。如果您只想从命令行使用它,就像使用ps-a v一样,那么您不需要安装python matplotlib推荐的依赖项。


1
2
3
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

使用它作为根,您可以获得每个进程使用内存的清晰输出。输出示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
     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]


那么time呢?

不是bash内置的time,而是您可以在which time中找到的,例如/usr/bin/time

在一个简单的ls上,它涵盖了以下内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
$ /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


这是对工具和问题的一个很好的总结:archive.org链接

我会引用它,这样更多的开发者会真正阅读它。

If you want to analyse memory usage of the whole system or to thoroughly analyse memory usage of one application (not just its heap usage), use exmap. For whole system analysis, find processes with the highest effective usage, they take the most memory in practice, find processes with the highest writable usage, they create the most data (and therefore possibly leak or are very ineffective in their data usage). Select such application and analyse its mappings in the second listview. See exmap section for more details. Also use xrestop to check high usage of X resources, especially if the process of the X server takes a lot of memory. See xrestop section for details.

If you want to detect leaks, use valgrind or possibly kmtrace.

If you want to analyse heap (malloc etc.) usage of an application, either run it in memprof or with kmtrace, profile the application and search the function call tree for biggest allocations. See their sections for more details.


除了答案中列出的解决方案外,您还可以使用linux命令"top";它提供了运行系统的动态实时视图,它给出了整个系统以及每个程序的CPU和内存使用率(百分比):

1
top

按程序PID过滤:

1
top -p <PID>

按程序名筛选:

1
top | grep <PROCESS NAME>

"top"还提供一些字段,例如:

virt—虚拟映像(kb):任务使用的虚拟内存总量。

res——驻留大小(kb):任务使用的非交换物理内存;res=code+data。

数据——数据+堆栈大小(KB):用于可执行代码以外的物理内存量,也称为"数据驻留集"大小或DRS。

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

参考这里。


对此没有一个单一的答案,因为您不能精确地确定进程使用的内存量。Linux下的大多数进程都使用共享库。例如,假设您要计算"ls"进程的内存使用率。是否只计算可执行文件"ls"使用的内存(如果可以隔离它的话)?伦敦银行同业拆借利率如何?或者运行"ls"所需的所有其他lib?

1
2
3
4
5
6
7
8
9
10
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将在程序的整个生命周期中为您提供更好的内存使用概况。


如果你的代码是C或C++,你就可以使用EDCOX1(2)来返回关于进程的内存和时间使用的各种统计信息。

但并非所有平台都支持这一点,并且将为内存使用选项返回0值。

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

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


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

我想大家都想知道的是"内存使用率"如下…在Linux中,单个进程可能使用的物理内存量大致可以分为以下几类。

  • 匿名映射内存

    • 私人的
      • .d dirty==malloc/mmmapped堆和堆栈分配和写入内存
      • .C clean==malloc/m映射堆和堆栈内存一旦分配、写入,然后释放,但尚未回收
    • s共享
      • .d dirty==malloc/mmaped堆可以在写入时获取副本,并在进程之间共享(已编辑)
      • .C clean==malloc/mmaped堆可以在写入时获取副本并在进程之间共享(已编辑)
  • M.N命名映射内存

    • 私人的
      • .d dirty==file mmaped written memory private
      • .C clean==映射的程序/库文本私有映射
    • s共享
      • .d dirty==文件被映射的写入内存共享
      • .C clean==映射库文本共享映射

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
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

如果你有时间去跑步,Valgrind会让人惊叹。valgrind --tool=massif是正确的解决方案。

然而,我开始举更多的例子,使用valgrind已经不再实用。有没有一种方法可以告诉程序的最大内存使用量(模块页大小和共享页)?

在真正的UNIX系统上,/usr/bin/time -v工作。然而,在Linux上,这不起作用。


我使用的是htop;这是一个非常好的控制台程序,类似于Windows任务管理器。


还有三种尝试方法:

  • ps aux --sort pmem它按%MEM对输出进行排序。
  • ps aux | awk '{print $2, $4, $11}' | sort -k2r | head -n 15它用管子分类。
  • top -a开始按%MEM进行顶部排序
  • (摘自此)


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    #!/bin/ksh
    #
    # Returns total memory used by process $1 in kb.
    #
    # See /proc/NNNN/smaps if you want to do something
    # more interesting.
    #

    IFS=$'
    '

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

    print $kb


    对更多"真实世界"用法的一个好测试是打开应用程序,然后运行vmstat -s并检查"活动内存"统计。关闭应用程序,等待几秒钟,然后再次运行vmstat -s。无论释放多少活动内存,应用程序显然在使用中。


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

    1
    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}'


    如果进程没有耗尽太多内存(可能是因为预期会出现这种情况,或者其他命令给出了这个初始指示),并且进程可以承受短时间的停止,则可以尝试使用gcore命令。

    1
    gcore <pid>

    检查生成的核心文件的大小,了解特定进程正在使用的内存量。

    如果进程使用数百个MEG或GiG,这将不会太好地工作,因为根据I/O性能,核心代可能需要几秒钟或几分钟才能创建。在核心创建过程中,进程停止(或"冻结")以防止内存更改。所以小心点。

    还要确保生成核心的装载点有足够的磁盘空间,并且系统不会对在该特定目录中创建的核心文件做出负面反应。


    我使用的是ARCHLinux,有一个很棒的包叫ps_mem

    1
    ps_mem -p <pid>

    实例输出

    1
    2
    3
    4
    5
    6
    7
    8
    $ 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
    =============================================

    获得勇气。把你的程序交给它运行,它会告诉你它的内存使用情况。

    这仅适用于运行一段时间并停止的程序。我不知道Valgrind是否可以处理已经运行的进程,或者不应该停止进程(如守护进程)。


    如果您想要比使用valgrind进行分析更快的东西,并且您的内核更老,并且您不能使用smaps,那么具有显示进程驻留集选项的ps(使用ps -o rss,command可以为您提供使用的实际非交换内存量的快速合理的_aproximation_


    编辑:只有当内存消耗增加时,它才能100%正常工作。

    如果要按给定进程(或一组已处理共享公用名,如google-chrome)监视内存使用情况,可以使用my bash脚本:

    1
    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;

    这将继续查找更改并打印它们。

    enter image description here


    检查shell脚本以检查Linux中应用程序的内存使用情况。也可以在Github和不带Paste和BC的版本中使用。


    我建议你用顶饰。你可以在这一页上找到一切。它能够为您的流程提供所有必要的关键绩效指标,还可以捕获到一个文件。


    这里还有一个关于Valgrind的投票,但是我想补充一点,你可以使用一个类似Alleyoop的工具来帮助你解释Valgrind产生的结果。

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


    虽然这个问题似乎是关于检查当前正在运行的进程,但我希望看到应用程序从头到尾使用的峰值内存。除了Valgrind,您还可以使用tstime,这非常简单。它测量"高水位"内存使用情况(RSS和虚拟)。从这个答案。


    基于对相关问题的回答。

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

    要求:

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

    笔记:

    • host-resources-mib::hrswrunperfcpu是此进程消耗的系统CPU资源总数的厘秒数。请注意,在多处理器系统上,该值在实际(挂钟)时间的一厘秒内可能会增加超过一厘秒。

    • host-resources-mib::hrswrunperfmem是分配给此进程的实际系统内存总量。

    **

    进程监视脚本:

    **

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    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

    /prox/xxx/numa_maps提供了一些信息:n0=????N1=????。但此结果可能低于实际结果,因为它只计算已接触的结果。


    使用Ubuntu中提供的内置"系统监视器"GUI工具