我需要控制当前python进程的内存使用情况。此过程是一个多线程python RPC服务器。
这些线程执行内存密集型工作(Threads使用ctypes调用内存密集型c库。所以这些python线程是真正并行的。)。
如果线程看到当前内存使用率高于阈值,我计划通过延迟对内存密集型函数的调用来控制此进程的内存使用量。
此应用程序在freeBSD 9.2上运行。
我需要帮助
1)如何获取当前进程的内存大小?因为,我会更频繁地做这个操作,我希望这个调用是轻量级的。
2)控制内存使用的想法是否合理?
答案 0 :(得分:0)
如果您可以安装外部库,则可以使用psutil
来监控系统性能。它非常轻巧,可以准确地测量内存,因此您应该能够调用它而不会导致任何严重的性能问题。如果您想要超级深入的内存信息,那么就会有一个名为memory_profiler
的相关库。可在此处找到https://pypi.python.org/pypi/memory_profiler,psutil
可在此处找到:https://github.com/giampaolo/psutil
是的,您应该能够在Python中操作内存。在Python中,可以使用内存接口中的方法完成内存管理。您可以根据需要释放和重新分配内存块。如果您想要更深入地了解Python如何在内部处理内存以及如何操作内存,我建议您查看Releasing memory in Python。
答案 1 :(得分:0)
鉴于大多数程序使用共享库,问题是哪个内存大小?我们暂时假设您正在谈论resident set size?
至少有两种方法可以解决这个问题;
ps -u
procstat -r <PID>
两者的例子:
> ps -u
USER PID %CPU %MEM VSZ RSS TT STAT STARTED TIME COMMAND
rsmith 820 0.0 0.0 10088 520 v0 I Fri11PM 0:00.01 -tcsh (tcsh)
rsmith 823 0.0 0.0 9732 32 v0 I+ Fri11PM 0:00.00 /bin/sh /usr/local/bin/startx
rsmith 836 0.0 0.0 26152 1480 v0 I+ Fri11PM 0:00.00 xinit /home/rsmith/.xinitrc -- /usr/local/bi
rsmith 840 0.0 0.1 135996 4904 v0 S Fri11PM 0:23.16 i3
rsmith 878 0.0 0.0 10088 1980 0 Ss Fri11PM 0:00.74 -tcsh (tcsh)
rsmith 5091 0.0 0.0 9388 1168 0 R+ 1:04AM 0:00.00 ps -u
rsmith 74939 0.0 0.1 10088 2268 1 Is+ Mon02PM 0:00.44 -tcsh (tcsh)
和
> procstat -r 820
PID COMM RESOURCE VALUE
820 tcsh user time 00:00:00.000000
820 tcsh system time 00:00:00.011079
820 tcsh maximum RSS 1840 KB
820 tcsh integral shared memory 2728 KB
820 tcsh integral unshared data 800 KB
820 tcsh integral unshared stack 256 KB
820 tcsh page reclaims 402
820 tcsh page faults 25
820 tcsh swaps 0
820 tcsh block reads 58
820 tcsh block writes 0
820 tcsh messages sent 0
820 tcsh messages received 0
820 tcsh signals received 1
820 tcsh voluntary context switches 105
820 tcsh involuntary context switches 0
在这种情况下,procstat
会为您提供最多信息。
procstat
程序使用libprocstat
来获取流程信息。所以你基本上有两个选择;
subprocess.check_output
来呼叫procstat
,然后解析其输出。ctypes
获取libprocstat
。第一种选择可能是最简单的,第二种可能是更轻量级。
关于控制记忆,有两个方面;
您可以通过主动del
- 不再需要的对象来尝试最小化Python内存使用量。
在ctypes
中,您可能必须为存储其数据的函数分配缓冲区(例如,使用ctypes.create_string_buffer
)或数组。这些是Python对象,可以这样处理。
您可以调用gc.collect()
强制进行垃圾回收。
但有时库会返回指向已分配的数据结构的指针。这些必须通过C库中的free()
或库提供的特殊功能释放。