文章内容

2021/8/21 18:23:21,作 者: 黄兵

使用 memory_profiler 诊断内存用量

最近使用多线程长时间运行任务,具体情况可以参考这篇文章:futures.ThreadPoolExecutor 内存耗尽相关问题,经过一天测试问题依然没有解决,只能分析看看哪里出了问题,导致内存占用居高不下。

在 Python 中分析内存占用,可以使用 memory_profiler 来分析。

安装 memory_profiler:

pip install memory_profiler

之后在需要分析的函数上面加装饰器:

from memory_profiler import profile
@profile
def ping_main(self, ip_list):
# fix ValueError: max_workers must be greater than 0
workers = min(self._num_worker, len(ip_list) if len(ip_list) > 0 else 1)
with futures.ThreadPoolExecutor(workers) as executor:
executor.map(self.ping, ip_list)

这里加入了 @profile 装饰器,现在开始分析,执行如下命令:

python python_program.py

运行一段时间之后就出现了占用内存的报告:

Filename: ping_monitor_main.py

Line #    Mem usage    Increment  Occurences   Line Contents
============================================================
    42     53.0 MiB     53.0 MiB           1       @profile
    43                                             def run_process_ping(self):
    44     53.0 MiB      0.0 MiB           1           ip_list = self.get_ip_list_by_csv()
    45     53.0 MiB      0.0 MiB           1           if ip_list:
    46     53.0 MiB      0.0 MiB           1               self._init_process_ping.ping_main(ip_list)


Filename: E:\Code\Service_Ping_Monitor\unit\process_ping.py

Line #    Mem usage    Increment  Occurences   Line Contents
============================================================
    86     53.0 MiB     53.0 MiB           1       @profile
    87                                             def ping_main(self, ip_list):
    88                                                 # fix ValueError: max_workers must be greater than 0
    89     53.0 MiB      0.0 MiB           1           workers = min(self._num_worker, len(ip_list) if len(ip_list) > 0 else 1)
    90     53.0 MiB      0.0 MiB           1           with futures.ThreadPoolExecutor(workers) as executor:
    91     50.8 MiB     -2.2 MiB           1               executor.map(self.ping, ip_list)


Filename: ping_monitor_main.py

Line #    Mem usage    Increment  Occurences   Line Contents
============================================================
    42     53.0 MiB     53.0 MiB           1       @profile
    43                                             def run_process_ping(self):
    44     53.0 MiB      0.0 MiB           1           ip_list = self.get_ip_list_by_csv()
    45     53.0 MiB      0.0 MiB           1           if ip_list:
    46     47.7 MiB     -5.3 MiB           1               self._init_process_ping.ping_main(ip_list)


Filename: E:\Code\Service_Ping_Monitor\unit\process_ping.py

Line #    Mem usage    Increment  Occurences   Line Contents
============================================================
    86     47.7 MiB     47.7 MiB           1       @profile
    87                                             def ping_main(self, ip_list):
    88                                                 # fix ValueError: max_workers must be greater than 0
    89     47.7 MiB      0.0 MiB           1           workers = min(self._num_worker, len(ip_list) if len(ip_list) > 0 else 1)
    90     47.7 MiB      0.0 MiB           1           with futures.ThreadPoolExecutor(workers) as executor:
    91     52.7 MiB      5.0 MiB           1               executor.map(self.ping, ip_list)


Filename: ping_monitor_main.py

Line #    Mem usage    Increment  Occurences   Line Contents
============================================================
    42     47.7 MiB     47.7 MiB           1       @profile
    43                                             def run_process_ping(self):
    44     47.7 MiB      0.0 MiB           1           ip_list = self.get_ip_list_by_csv()
    45     47.7 MiB      0.0 MiB           1           if ip_list:
    46     52.7 MiB      5.0 MiB           1               self._init_process_ping.ping_main(ip_list)

这样就可以分析哪里出了问题,导致内存占用过高。


参考资料:

1、Memory profiling in Python using memory_profiler

2、《Python 高性能编程》[美] Micha Gorelick Ian Ozsvald 著


黄兵个人博客原创。

转载请注明出处:黄兵个人博客 - 使用 memory_profiler 诊断内存用量

分享到:

发表评论

评论列表