【问题标题】:Python multithreading - memory not released when ran using While statementPython多线程-使用While语句运行时未释放内存
【发布时间】:2018-06-05 16:31:43
【问题描述】:

我构建了一个通过多线程(通过 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

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

但是,我想运行上述脚本 20 次(批处理排序), 所以我把提到的脚本变成了一个函数,并使用下面的代码运行这个函数:

def multithreaded_script():
   my script #code from above

x = 0
while x<20:
  x +=1
  multithredaded_script()

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

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

我试过了:

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

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

提前谢谢你。

【问题讨论】:

  • 我还尝试导入垃圾收集模块( import gc gc.enable() ),并在每个工作函数运行后手动添加 gc.collect() ......没有骰子。
  • 感谢您为我指明正确的方向(使用内存分析器)。这个包中的逐行分析看起来不错,但是由于某种原因我无法安装它。知道是否有其他软件包提供逐行内存分析?

标签: python multithreading memory-leaks jupyter-notebook


【解决方案1】:

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

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

实现相当简单:

from pympler.tracker import SummaryTracker
tracker = SummaryTracker()

~~~~~~~~~YOUR CODE

tracker.print_diff()

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

在每个函数的末尾添加“return”可以解决问题。

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-11
    • 2011-08-23
    • 2014-06-14
    • 1970-01-01
    • 2013-05-12
    相关资源
    最近更新 更多