MPIRE WorkerPool持续运行引发内存泄漏问题求助
针对你遇到的mpire WorkerPool长期运行内存泄漏问题,分享几个可行的解决方向:
先升级mpire到最新版本
很多内存泄漏问题是库的已知bug,后续版本会修复。执行pip install --upgrade mpire更新后再测试,这是最容易尝试的方案,大概率能解决问题。给WorkerPool设置
maxtasksperchild参数
不用完全关闭keep-alive,你可以让每个worker处理指定次数的任务后自动重启。比如设置maxtasksperchild=1000,每个worker跑1000次map任务后重启一次——既不会因为频繁重启拖慢速度,又能定期清理泄漏的内存。修改后的代码:def workerPoolFunction(): mpirePool = mpire.WorkerPool(n_jobs=4, maxtasksperchild=1000) mpirePool.set_shared_objects(nonPicklableObject) mpirePool.set_keep_alive(True) while(True): results = mpirePool.map(workerFunction)定期手动重启WorkerPool
如果上面的方法没用,就在循环里加个计数器,每跑N次循环就重启一次pool。比如每5000次循环重启一次,泄漏的内存会被彻底释放,而且因为重启频率低,对性能的影响几乎可以忽略:def workerPoolFunction(): mpirePool = None cycle_count = 0 max_cycles = 5000 while(True): if mpirePool is None or cycle_count >= max_cycles: if mpirePool is not None: mpirePool.close() mpirePool.join() mpirePool = mpire.WorkerPool(n_jobs=4) mpirePool.set_shared_objects(nonPicklableObject) mpirePool.set_keep_alive(True) cycle_count = 0 results = mpirePool.map(workerFunction) cycle_count += 1改用
imap替代mapmap会一次性生成所有结果并存在列表里,而imap是迭代返回结果,内存管理更灵活。把mpirePool.map(workerFunction)改成list(mpirePool.imap(workerFunction)),说不定能缓解泄漏问题。检查共享对象的引用
虽然你排除了工作函数的问题,但再确认下nonPicklableObject内部有没有隐性的引用泄漏——比如它是否持有一些动态生成的资源,哪怕worker里没显式保存,也可能被隐式引用。可以尝试用weakref来管理这个对象的引用,避免不必要的内存占用。
内容的提问来源于stack exchange,提问作者Viktor Katzy

