Python 多线程 - 使用 While 语句运行时未释放内存

Fly*_*ra1 6 python multithreading memory-leaks jupyter-notebook

我构建了一个通过多线程(通过 Jupyter Notebook、python 2.7、anaconda)启动了 XX 次的刮板(worker)。脚本采用以下格式,如 python.org 所述:

def worker():
    while True:
        item = q.get()
        do_work(item)
        q.task_done()

q = Queue()
for i in range(num_worker_threads):
     t = Thread(target=worker)
     t.daemon = True
     t.start()

for item in source():
    q.put(item)

q.join()       # block until all tasks are done
Run Code Online (Sandbox Code Playgroud)

当我按原样运行脚本时,没有问题。脚本完成后释放内存。

但是,我想运行上述脚本 20 次(排序的批处理),所以我将提到的脚本转换为一个函数,并使用以下代码运行该函数:

def multithreaded_script():
   my script #code from above

x = 0
while x<20:
  x +=1
  multithredaded_script()
Run Code Online (Sandbox Code Playgroud)

每次迭代都会增加内存,最终系统开始将其写入磁盘。

有没有办法在每次运行后清除内存?

我试过:

  1. 将所有变量设置为 None
  2. sleep(30)在每次迭代结束时设置(以防 ram 需要时间释放)

似乎没有任何帮助。关于在 While 语句中每次运行后我还可以尝试清除内存的其他想法?如果没有,有没有更好的方法来执行我的脚本 XX 次,这不会吃掉 ram?

先感谢您。

Fly*_*ra1 3

TL;DR 解决方案:确保以 return 结束每个函数,以确保所有局部变量都从 ram** 中销毁

根据 Pavel 的建议,我使用了内存跟踪器(不幸的是,建议 mem 跟踪器对我不起作用,所以我使用了Pympler。)

实现相当简单:

from pympler.tracker import SummaryTracker
tracker = SummaryTracker()

~~~~~~~~~YOUR CODE

tracker.print_diff()
Run Code Online (Sandbox Code Playgroud)

跟踪器给出了很好的输出,这显然表明函数生成的局部变量没有被破坏。

在每个函数末尾添加“ return ”解决了这个问题。

要点:
如果您正在编写一个处理信息/生成局部变量的函数,但不将局部变量传递给其他任何东西 - >请确保无论如何都以return结束该函数。这将防止您可能遇到的内存泄漏问题。

关于内存使用和 BeautifulSoup 的附加说明: 如果您使用具有多线程和多个工作线程的 BeautifulSoup / BS4,并且可用内存数量有限,您还可以soup.decompose()在使用完后立即销毁 soup 变量,而不是等待函数返回/代码停止运行。