Python '';。ThreadPoolExecutor eat内存中的join()
请尝试以下代码:Python '';。ThreadPoolExecutor eat内存中的join(),python,multithreading,memory-leaks,Python,Multithreading,Memory Leaks,请尝试以下代码: import gc import random from concurrent.futures import ThreadPoolExecutor zen = "Special cases aren't special enough to break the rules. " def abc(length: int): msg = ''.join(random.sample(zen, length)) print(msg) del msg if
import gc
import random
from concurrent.futures import ThreadPoolExecutor
zen = "Special cases aren't special enough to break the rules. "
def abc(length: int):
msg = ''.join(random.sample(zen, length))
print(msg)
del msg
if __name__ == '__main__':
pool = ThreadPoolExecutor(max_workers=8)
while True:
for x in range(256):
pool.submit(abc, random.randint(2, 6))
print('===================================================')
gc.collect()
如果代码在没有ThreadPoolExecutor的情况下运行,则可能需要大约8MB的内存,或者使用str()而不是“”。join()大约需要30MB的内存。但这段代码一直在毫无限制地吞噬RAM。我认为这是由random.sample或其他原因造成的,但它证明了ThreadPoolExecutor中的“”join()导致了此问题
这让我很困惑,因为没有模块相互导入(仅共享zen),del和Gc都不能工作:(
ps:请注意,无限循环不是问题。当您运行以下操作时:
while True:
print(1234567)
内存使用将保持在某一行以下(上面的代码可能不超过1MB?)。顶部的代码没有递增的列表或dict,并且变量在模块末尾已被删除。因此,当线程完成时,它应该像我所想的那样被清除,这显然不是
pss:让我们这样说:问题的原因是''中的任何内容。join()将不会被回收。就像我们这样更改abc模块一样:
tmp = random.sample(zen, length)
msg = ''.join(tmp)
print(msg[:8])
del msg, tmp
Gc工作有效,使用量保持在26MB左右
那么,在使用“”时,我是否遗漏了什么?join()或python语言有一个bug?当您在没有线程的情况下运行代码时,每个句子都将完全执行,这意味着在内部循环结束后将调用
gc.collect()
但是,当您使用线程执行代码时,将在最近一个线程结束之前调用一个新线程,因此新线程的数量将迅速增加,并且由于线程数量没有限制,因此您的CPU将无法处理更多的线程,从而导致线程的累积。但是这里有一个无限循环。您的gram永远不会结束。由于您没有获得提交的
结果,因此池会不断增长。您的while循环从未中断。显然,它会不断增长。很抱歉,我没有明确说明。当您使用单个线程或不使用“”。join()运行时,即使是无限循环,内存使用量也会保持在一定的范围内,例如8MB或更高。它不会(重要声明3次)增长到数百MB或更高(类似的例子是4096个线程占用13GB RAM)。只有“循环使其增长”对我来说没有意义,兄弟。