我已经found the following question,但我想知道是否有更快更脏的方法来估算python解释器当前用于我的脚本的内存量,而不依赖于外部库
我来自PHP,为了这个目的,我常常使用memory_get_usage()和memory_get_peak_usage(),我希望找到一个等价物。
答案 0 :(得分: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
它返回当前和峰值驻留内存大小(这可能是人们在谈论应用程序使用多少RAM时的意思)。可以很容易地扩展它以从/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
答案 1 :(得分:17)
您还可以使用标准库模块getrusage()
中的resource
函数。生成的对象具有属性ru_maxrss
,该属性为调用进程提供总峰值内存使用量:
>>> import resource
>>> resource.getrusage(resource.RUSAGE_SELF).ru_maxrss
2656
Python docs并不清楚单位究竟是什么,但getrusage(2)
的{{3}}将单位描述为千字节。
Linux手册页不清楚,但它似乎等同于接受的答案中描述的/proc/self/status
信息(即千字节)。对于与上述相同的过程,在Linux上运行,接受的答案中列出的函数给出:
>>> memory_usage()
{'peak': 6392, 'rss': 2656}
这可能不像/proc/self/status
解决方案那么容易使用,但它是标准库,因此(如果单位是标准的)它应该是跨平台的,并且可以在缺少{{的系统上使用1}}(例如Mac OS X和其他Unix,也许是Windows)。
此外,/proc/
函数也可以getrusage()
用于获取子进程的使用,并且(在某些系统上)resource.RUSAGE_CHILDREN
用于总(自我和子)进程使用。< / p>
这将涵盖resource.RUSAGE_BOTH
案例,但不包括峰值使用情况。我不确定memory_get_usage()
模块中的任何其他函数是否可以提供峰值使用。
答案 2 :(得分:10)
答案 3 :(得分:2)
尝试heapy
答案 4 :(得分:1)
/proc/self/status
中也包含/proc/self/statm
中相同类型的数据。但是,解析起来更容易,因为它只是一个用空格分隔的列表,其中包含多个statistics。我无法确定两个文件是否总是存在。
/ proc / [pid] / statm
提供有关内存使用情况的信息,以页为单位。 列为:
- 大小(1)程序总大小 (与/ proc / [pid] / status中的VmSize相同)
- 居民(2)居民集合大小 (与/ proc / [pid] / status中的VmRSS相同)
- 共享的(3)个常驻共享页面数(即由文件支持) (与/ proc / [pid] / status中的RssFile + RssShmem相同)
- 文本(4)文本(代码)
- lib(5)库(从Linux 2.6开始不使用;始终为0)
- 数据(6)数据+堆栈
- dt(7)脏页(自Linux 2.6起未使用;始终为0)
这是一个简单的例子:
from pathlib import Path
from resource import getpagesize
PAGESIZE = getpagesize()
PATH = Path('/proc/self/statm')
def get_resident_set_size() -> int:
"""Return the current resident set size in bytes."""
# statm columns are: size resident shared text lib data dt
statm = PATH.read_text()
fields = statm.split()
return int(fields[1]) * PAGESIZE
data = []
start_memory = get_resident_set_size()
for _ in range(10):
data.append('X' * 100000)
print(get_resident_set_size() - start_memory)
这会产生一个看起来像这样的列表:
0
0
368640
368640
368640
638976
638976
909312
909312
909312
您可以看到在大约分配了3个100,000字节后,它跳了约300,000字节。
答案 5 :(得分:0)
/proc/self/status
具有以下相关密钥:
因此,如果关注的是驻留内存,我可以使用以下代码来检索它:
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,它解释了getrusage
的{{1}}并不总是一个实用的衡量标准。另请注意,ru_maxrss
可能与VmHWM
不同(我在某些情况下看到ru_maxrss
更大)。但在简单的情况下它们是相同的:
ru_maxrss
此外,这是一个非常易于理解但信息丰富的case study by atop authors,它解释了什么是内核,虚拟和驻留内存,以及它们如何相互依赖。