如何在Python中使用psutil获得程序的最大内存使用率
我使用下面的代码来获取程序的最大内存使用量如何在Python中使用psutil获得程序的最大内存使用率,python,unix,python-2.7,memory,Python,Unix,Python 2.7,Memory,我使用下面的代码来获取程序的最大内存使用量 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)
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)
问题有时是,对于程序的初始运行,内存使用量输出为(0,0),但随后它会显示正确的输出。我不知道为什么会这样。对于一些程序,例如在C++中的Hello World程序,输出是“代码> PMEM(RSS=4096,VMS=315392),它大约为0.3M(我认为输出是字节),但是在IDENo.com中运行Hello World程序将输出作为~3M。为什么会出现这种情况
cmd是可执行文件的名称
命令打印子进程的输出。检查输出(['ps','v','p','str(p.pid)])
PID TTY STAT TIME MAJFL TRS DRS RSS%MEM命令
16150分/16 Z+0:00 0.0[a.out]
<我的一个C++程序:
`int a[1000000];
int main()
{
return 0;
}`
有时返回pmem(rss=4096,vms=4313088),有时返回pmem(rss=0,vms=0)表示子进程是一个(它是死的,但它的状态尚未被父进程读取(p.poll()
或p.wait()
)。对于这样的过程,psutil
和ps
都显示RSS
为零
结果取决于子进程是否会在p之前退出。将调用memory_info()
。这是一场比赛。如果在C++程序的出口添加一个延迟,则在子进程退出之前调用“代码> p MeMyYyIn()/Cype),并且应该得到非零结果。
问题是我可以让任意程序进行评估。语言也不是固定不变的。这个问题难道没有一个优雅的解决方案吗 您可能需要操作系统支持来保存子进程的内存使用信息,即使在它退出后也是如此。或者,您可以使用内存分析器(如
valgrind
)运行该程序并读取其结果。要收集结果:
$ valgrind --tool=massif cmd arg1 arg2
要查看结果,可以使用ms\u print
:
$ ms_print massif.out.* | less
或GUI
一个更简单的解决方案:
GNU time使用wait3()
填充可用的资源使用信息。可以在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)
我比较了psutil.Process.memory\u info
(rss)返回的最大值与os.wait4
返回的ru\u maxrss
值以及valgrind--tool=massif
报告的最大总内存:它们是相似的
另见:
open("/proc/13420/statm", O_RDONLY) = 3
read(3, "0 0 0 0 0 0 0\n", 1024) = 14
如果将示例修改为使用睡眠之类的功能,您会注意到psutils始终返回内存使用率
#include <iostream>
#include <unistd.h>
int main()
{
std::cout << "Hello World.. sleeping!";
sleep(3);
}
一种简单的方法是使用/usr/bin/time命令,在大多数平台上,该命令将为您提供启动或使用valgrind的进程的平均总内存使用量,正如J.F Sebastian所建议的那样。。。当我正在研究和测试我的答案时,他发了帖子;)
你能用一个已知的程序如
[“python”、“-c”、“pass”]
复制它吗?您确定没有抑制异常,即Popen()
成功启动?不相关:如果stderr=PIPE
那么您应该从p.stderr
中读取,否则如果进程在stderr上生成足够的输出来填充相应的OS管道缓冲区,则该进程可能会永远阻塞。@J.F.Sebastian删除了stderr。打印子进程的内容是什么。检查输出(['ps','v','p','p',str p.pid)])
show?@J.F.Sebastian I添加了异常处理。有时输出是(0,0),没有例外,但是我得到了一个偶数,当pmem(rss=4096,vms=4313088)。。。这是因为竞争条件,因为我将print语句放在p.memory_info()之后。在调用ps
时,子进程可能已经死亡,但在p.memory_info()期间它仍然处于活动状态。问题是我可以让任意程序进行计算。语言也不是固定不变的。这个问题是否有一个优雅的解决方案?我尝试使用/usr/bin/time-v./a.outout.txt
但是常驻集的大小仍然不准确,它非常小。我添加了基于os.wait4()
的解决方案。它与原始的基于资源的解决方案类似。您是否将它们与psutil
,valgrind
结果进行了比较?/usr/bin/time-f%M
将打印“进程在其生命周期内的最大驻留集大小,以KB为单位”,为什么我运行程序时rss大小如此之小。对于实际内存使用量约为49MB的程序,我的最大rss大小是3292KB?我的系统有问题吗?
#include <iostream>
#include <unistd.h>
int main()
{
std::cout << "Hello World.. sleeping!";
sleep(3);
}
a.out
meminfo(rss=286720, vms=12931072)
Hello World.. sleeping!0.00user 0.00system 0:03.00elapsed 0%CPU
(0avgtext+0avgdata 1144maxresident)k
0inputs+0outputs (0major+348minor)pagefaults 0swaps