尝试这样的代码:
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?)。顶部的代码没有增加的列表或字典,&变量已经在模块的末尾。因此,当我认为线程完成时应该清理它,显然不是。
pss:让我们这样说:问题的原因是' .join()不会被回收。好像我们这样改变了abc模块:tmp = random.sample(zen, length)
msg = ''.join(tmp)
print(msg[:8])
del msg, tmp
Gc有效运行,使用量保持在26MB左右。
答案 0 :(得分:0)
当您运行没有线程的代码时,每个语句将完全执行,这意味着gc.collect()
将在内循环结束后被调用。
但是,当您使用线程执行代码时,将在最新线程结束之前调用一个新线程,因此新线程的数量将迅速增加,并且由于对线程数量没有限制,因此您拥有的线程数将超过您的CPU可以处理导致线程堆积的情况。