如何在Linux上正确地测量进程的内存使用情况?

3
我想在Linux系统中(特别是Ubuntu 15.04),测量进程的内存使用情况,但我不确定如何正确完成。我希望这些测量结果与free命令相关,以便发现的总内存使用量对应于free报告的值(缓存除外)。
到目前为止,我已经编写了此Python脚本,但它与free不一致,因为它报告较低的总内存使用量:
#!/usr/bin/env python
from collections import OrderedDict
import os.path
import re


def parse_mem_file(filename):
    data = OrderedDict()
    with open(filename, 'rb') as f:
        for line in f:
            splittage = line.split(':')
            data[splittage[0]] = splittage[1].strip()
    return data


def get_process_mem_usage():
    re_pid = re.compile(r'^\d+$')
    re_mem = re.compile(r'^(\d+) .+$')
    pid2usage = {}
    for pid in [d for d in os.listdir('/proc') if re_pid.match(d)]:
        fpath = os.path.join('/proc', pid, 'status')
        try:
            data = parse_mem_file(fpath)
        except IOError:
            continue

        try:
            pid2usage[pid] = int(re_mem.match(data['VmHWM']).group(1)) / 1024.
        except KeyError:
            continue

    return OrderedDict(
        sorted(pid2usage.iteritems(), key=lambda x: x[1], reverse=True))


pid2usage = get_process_mem_usage()
total_usage = sum(pid2usage.values())
print('Total memory usage: {:.2f}'.format(total_usage))
for pid, usage in pid2usage.iteritems():
    print('{}: {:.2f} MB'.format(pid, usage))

如何调整此程序以报告与free程序报告相符的内存使用情况?

为了理解背景,问题是我的服务器上的内存使用量随着时间的推移而增加,直到大量交换内存被使用并因此导致速度变慢。我想知道这个问题的原因。

1个回答

1

free在Linux上读取/proc/meminfo文件(参见proc(5))。您可以通过调用strace free来确保它,输出不是很长。

P.S.由于您的评论进行了更新。

free显示有关物理内存的信息。它计算使用的物理内存量为MemTotal-MemFree。因此,我们对系统中进程使用的物理内存感兴趣。

首先,您正在使用/ proc /<pid>/status文件的VmHWM字段。从proc(5)

VmHWM:峰值常驻集大小(“高水位标记”)。

也就是说,给定进程在其生命周期内使用的最大物理内存量。它不是进程的当前内存使用情况。如果要获取当前的物理内存使用情况,请查看VmRSS

VmRSS:常驻集大小。

第二件事。文件/proc/<pid>/status旨在供人阅读。对于程序员来说,更容易解析/proc/<pid>/statm并获取第二列中的值,该值与/proc/<pid>/status中的VmRSS相同。
现在最重要的部分。因为我们考虑的是物理内存,所以我们应该记住它是一个系统范围的东西。无法通过计算系统中所有进程的常驻集大小之和来计算物理内存的数量,原因有很多。首先,不仅用户空间进程使用系统中的物理内存,内核也使用 -- 所有设备驱动程序、内核线程和其他一些东西。其次,进程之间可以共享内存。
总之,《proc(5)》是一本非常好的读物。
P.P.S. 关于:

为了背景,问题在于我的服务器上的内存使用量随着时间的推移而增加,直到使用了大量交换内存,结果减慢了很多。我想知道这个问题的原因。

如果您想诊断哪些进程消耗了所有内存,可以调用top并按使用物理内存的份额排序进程(键入“M”)。

但是如何测量单个进程的内存使用情况,以便总和对应于空闲,这是问题所在。 - aknuds1
那里有很多有趣的信息,但它并没有真正让我更接近解决我的问题。首先,我想编写一个程序来找出是什么在占用内存。其次,运行进程中“VmRSS”的总和仅为128 MB,而“free”显示大约使用了955 MB RAM和1045 MB交换空间。 - aknuds1
当我在top命令中按内存使用率排序时,它只显示docker和node在顶部,分别占用4.9%和2.5%的内存使用率。我还没有找到任何迹象表明为什么会使用1 GB的交换空间。 - aknuds1
@aknuds1 可以考虑在 superuser.com 或 serverfault.com 上提问。 - Oleg Andriyanov
我在ServerFault上写了一个关于Docker交换使用的具体问题,因为我通过top发现它正在使用大约780 MB的交换空间。 - aknuds1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接