文章内容
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 著
黄兵个人博客原创。
评论列表