简体   繁体   English

如何在Python中使用psutil获取程序的最大内存使用量

[英]How to get the max memory usage of a program using psutil in Python

I am using the following code to get the max memory usage of the program. 我使用以下代码来获取程序的最大内存使用量。

    import os, subprocess , psutil
    def mem(cmd):
        try:
            with open('in.txt','r') as infile, open('out.txt', 'w') as outfile:
                p=psutil.Popen("./"+cmd,shell=False,stdin=infile,stdout = outfile)
            print p.memory_info()
        except Exception:
             print "Error"
    cmd=raw_input()
    mem(cmd)

The problem is sometimes for initial runs of the program the memory usage output is (0,0) but subsequently it displays the correct output. 问题有时是程序的初始运行,内存使用输出为(0,0),但随后显示正确的输出。 I dont why this happening. 我不知道为什么会这样。 For some programs such as the hello world program in c++ the output is pmem(rss=4096, vms=315392) which is about 0.3M( I think the output is in bytes ) but running the hello world program in ideone.com gives the output as ~3M. 对于某些程序,例如c ++中的hello world程序,输出是pmem(rss=4096, vms=315392) ,大约0.3M(我认为输出是以字节为单位)但是在ideone.com中运行hello world程序给出了输出为~3M。 Why is there this disperency? 为什么会有这种不合理?

cmd is the name of the executable. cmd是可执行文件的名称。

The output of command print subprocess.check_output(['ps', 'v', '-p', str(p.pid)]) 命令print subprocess.check_output(['ps', 'v', '-p', str(p.pid)])

PID TTY STAT TIME MAJFL TRS DRS RSS %MEM COMMAND 16150 pts/16 Z+ 0:00 0 0 0 0 0.0 [a.out] <defunct>

One of my sample C++ program: 我的一个示例C ++程序:

`int a[1000000];
int main()
{
    return 0;
}`

returns pmem(rss=4096, vms=4313088) sometimes and pmem(rss=0,vms=0) sometimes 有时返回pmem(rss = 4096,vms = 4313088),有时返回pmem(rss = 0,vms = 0)

The problem here is that psutils takes a quick snapshot from the /proc filesystem, as you can see in the source . 这里的问题是psutils从/ proc文件系统获取快速快照,正如你在源代码中看到的那样。

When you run your hello world example, in some cases it finishes before python gets a chance to read the values from /proc. 当你运行hello world示例时,在某些情况下,它会在python有机会从/ proc读取值之前完成。

Once the process is finished, it effectively no longer consumes any ram. 一旦完成该过程,它实际上不再消耗任何内存。 You can confirm this with an strace. 您可以通过strace确认这一点。

open("/proc/13420/statm", O_RDONLY)     = 3
read(3, "0 0 0 0 0 0 0\n", 1024)        = 14

If you modify your example to use something like sleep, you'll notice that psutils consistently gives memory usage back. 如果你修改你的例子以使用类似睡眠的东西,你会注意到psutils一直给予内存使用。

#include <iostream>
#include <unistd.h>

int main()
{
  std::cout << "Hello World.. sleeping!";
  sleep(3);
}

Output of your python script... 输出你的python脚本......

a.out
meminfo(rss=286720, vms=12931072)

One simple way to accomplish what you are trying to do, is by using the /usr/bin/time command, which on most platforms will give you the average total memory usage of the process you launch OR use valgrind as JF Sebastian suggests... whom posted as I was researching and testing my answer ;) 一个简单的方法来完成你要做的事情,就是使用/ usr / bin / time命令,在大多数平台上,它会给你你启动的进程的平均总内存使用量,或者使用valgrind作为JF Sebastian建议的...谁在我研究和测试我的答案时张贴;)

Hello World.. sleeping!0.00user 0.00system 0:03.00elapsed 0%CPU     
(0avgtext+0avgdata 1144maxresident)k
0inputs+0outputs (0major+348minor)pagefaults 0swaps

<defunct> means that the subprocess is a zombie process (it is dead but its status has not been read yet by the parent ( p.poll() or p.wait() )). <defunct>表示子进程是一个僵尸进程 (它已经死了但它的状态还没有被父p.poll()读取( p.poll()p.wait() ))。 It seems both psutil and ps shows RSS to be zero for such processes. 似乎psutilps表明这些进程的RSS为零。

The result depends on whether the subprocess will exit sooner than p.memory_info() is called. 结果取决于子p.memory_info()是否会比p.memory_info()更早退出。 It is a race. 这是一场比赛。 If you add a delay at the exit in the C++ program then p.memory_info() may be called before the subprocess exits and you should get non-zero results. 如果在C ++程序的出口处添加延迟,则可以在子p.memory_info()退出之前调用p.memory_info()并且应该得到非零结果。

The problem is that I can get arbitrary programs to evaluate . 问题是我可以得到任意程序来评估。 The language is also not fixed. 语言也没有修复。 Isn't there an elegant solution to this problem? 这个问题没有一个优雅的解决方案吗?

You might need OS support to save info about the memory usage by a subprocess even after it exits. 您可能需要操作系统支持来保存子进程的内存使用情况信息,即使它已退出。 Or you could run the program using a memory profiler such as valgrind and read its results. 或者您可以使用内存分析器(如valgrind运行程序并读取其结果。 To collect results: 收集结果:

$ valgrind --tool=massif cmd arg1 arg2 

To see the results, you could use ms_print : 要查看结果,可以使用ms_print

$ ms_print massif.out.* | less

Or GUI Massif-Visualizer 或GUI Massif-Visualizer

@mdadm suggested a simpler solution: time command : @mdadm提出了一个更简单的解决方案: time命令

from subprocess import Popen, PIPE

p = Popen(['time', '-f', '%M'] + args, stderr=PIPE)
ru_maxrss = int(p.communicate()[1])
print("Maximum rss %d KB" % ru_maxrss)

GNU time uses wait3() to populate resource usage info if it is available. GNU时间使用wait3()来填充资源使用信息(如果可用)。 It can be called in Python: 它可以在Python中调用:

import os
from subprocess import Popen

p = Popen(args)
ru = os.wait4(p.pid, 0)[2]
print("Maximum rss %d KB" % ru.ru_maxrss)

I've compared the maximum value returned by psutil.Process.memory_info (rss) with ru_maxrss value returned by os.wait4 and with the maximum total memory reported by valgrind --tool=massif : they are similar . 我比较了返回的最大值psutil.Process.memory_info (RSS)与ru_maxrss通过返回的值os.wait4与报道的最大内存总量valgrind --tool=massif它们是相似的

See also: 也可以看看:

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM