2009-05-22 129 views

回答

31

在Linux和其它系统的一个简单的解决方案与/proc/self/status是下面的代码,我在我的一个项目中使用:

def memory_usage(): 
    """Memory usage of the current process in kilobytes.""" 
    status = None 
    result = {'peak': 0, 'rss': 0} 
    try: 
     # This will only work on systems with a /proc file system 
     # (like Linux). 
     status = open('/proc/self/status') 
     for line in status: 
      parts = line.split() 
      key = parts[0][2:-1].lower() 
      if key in result: 
       result[key] = int(parts[1]) 
    finally: 
     if status is not None: 
      status.close() 
    return result 

它返回电流和峰值常驻内存的大小(这可能是人们谈论应用程序使用多少内存时的含义)。很容易将其扩展为从/proc/self/status文件中获取其他信息。

对于好奇:中cat /proc/self/status全力输出看起来是这样的:

% cat /proc/self/status 
Name: cat 
State: R (running) 
Tgid: 4145 
Pid: 4145 
PPid: 4103 
TracerPid:  0 
Uid: 1000 1000 1000 1000 
Gid: 1000 1000 1000 1000 
FDSize: 32 
Groups: 20 24 25 29 40 44 46 100 1000 
VmPeak:  3580 kB 
VmSize:  3580 kB 
VmLck:   0 kB 
VmHWM:  472 kB 
VmRSS:  472 kB 
VmData:  160 kB 
VmStk:  84 kB 
VmExe:  44 kB 
VmLib:  1496 kB 
VmPTE:  16 kB 
Threads:  1 
SigQ: 0/16382 
SigPnd: 0000000000000000 
ShdPnd: 0000000000000000 
SigBlk: 0000000000000000 
SigIgn: 0000000000000000 
SigCgt: 0000000000000000 
CapInh: 0000000000000000 
CapPrm: 0000000000000000 
CapEff: 0000000000000000 
CapBnd: ffffffffffffffff 
Cpus_allowed: 03 
Cpus_allowed_list:  0-1 
Mems_allowed: 1 
Mems_allowed_list:  0 
voluntary_ctxt_switches:  0 
nonvoluntary_ctxt_switches:  0 
+2

是以kb或字节为单位的峰值/常驻? – Shabbyrobe 2009-05-23 01:58:42

+1

好问题 - 以千字节为单位,我将这些信息添加到原始答案中。 – 2009-05-23 09:16:54

+0

非常感谢您的回答。顺便说一句,如果我产生了一堆线程,即使居民保持相对较低,您是否也会明白为什么峰值高于80mb(!!!)?另外,你是否有任何线索知道如何在Win32上做到这一点? – Shabbyrobe 2009-05-25 13:14:27

17

你也可以从标准库模块resource使用getrusage()功能。得到的对象具有属性ru_maxrss,这使总内存调用进程:

>>> import resource 
>>> resource.getrusage(resource.RUSAGE_SELF).ru_maxrss 
2656 

Python docs不在单位究竟清楚,但对于Mac OS X man page描述getrusage(2)单位为千字节。

Linux手册页不清楚,但它似乎等同于接受的答案中描述的/proc/self/status信息(即千字节)。出于与上述相同的过程,在Linux上运行,在接受的答案中所列的功能得到:

>>> memory_usage()          
{'peak': 6392, 'rss': 2656} 

这可能不是那么容易的/proc/self/status解决方案中使用,但它是标准库,因此(提供这些单元是标准的),它应该是跨平台的,并且可用于缺少/proc/(例如Mac OS X和其他Unix,也许是Windows)的系统。

此外,getrusage()函数还可以给出resource.RUSAGE_CHILDREN以获取子进程的使用情况,以及(在某些系统上)获得总(自我和子进程)使用情况的resource.RUSAGE_BOTH

这将涵盖memory_get_usage()的情况,但不包括峰值使用情况。我不确定resource模块是否有其他功能可以提供高峰使用。

10

接受答案规则,但使用psutil可能更容易(也更便携)。它做同样的事情,还有更多。

更新:muppy也非常方便(并且比guppy/heapy记录更好)。

0

/proc/self/status具有以下相关的键:

  • VmPeak:峰值虚拟内存大小。
  • VmSize:虚拟内存大小。
  • VmHWM:高峰居民组大小(“高水位”)。
  • VmRSS:居民组大小。

因此,如果关注的是驻留内存,下面的代码可我用来检索:

def get_proc_status(keys = None): 
    with open('/proc/self/status') as f: 
     data = dict(map(str.strip, line.split(':', 1)) for line in f) 

    return tuple(data[k] for k in keys) if keys else data 

peak, current = get_proc_status(('VmHWM', 'VmRSS')) 
print(peak, current) # outputs: 14280 kB 13696 kB 

这里是一个article by memory_profiler's author是解释getrusageru_maxrss并不总是可行的措施。还请注意,VmHWM可能与ru_maxrss不同(我在某些情况下看到的ru_maxrss更大)。但在简单的情况下,他们都是一样的:

import resource 


def report(): 
    maxrss = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss 
    peak, current = get_proc_status(('VmHWM', 'VmRSS')) 
    print(current, peak, maxrss) 


report() 

s = ' ' * 2 ** 28 # 256MiB 
report() 

s = None 
report() 

另外这里是一个非常易懂而内容case study by atop authors这说明了什么是仁,虚拟和驻留内存,以及它们是如何相互依存的。