Ребят есть кусок рабочего кода, я его упростил до предела, после работы жрёт 3 гига памяти, и через gc.collect() не хочет её освобождать.
Может кто-нибудь пожалуйста исправить утечку?
В функции engine я раздуваю объект, и всё труба, вернуть память назад уже никак не получается.
Код:
from concurrent.futures import ProcessPoolExecutor
import time
import gc
import pdb
from queue import Queue
# через сколько выполнений обнулять пул
POOL_RESET_PERIOD = 10
# сколько заданий закидывать в пул
POOL_TASK_CHUNK = 10
q = Queue()
# класс в котором будет тяжёлый объект
class MyHugeTask:
def __init__(self):
self.cont = {}
# функция обработчик
def engine(box):
# раздуваем объект чтобы он начал жрать память
box.cont["123"] = "123"*1000*100*100*10
return box
# закидываем таски для теста
for i in range(50):
q.put(MyHugeTask())
def main_run(queue):
print("принято заданий: {}".format(queue.qsize()))
pool = None
count = 0
it = 0
while True:
it += 1
# reset pool через каждые N выполнений
if pool is None or not count % POOL_RESET_PERIOD:
if pool is not None:
pool.shutdown()
pool = ProcessPoolExecutor(max_workers=1)
print('Pool reseted')
if queue.qsize() is 0:
break
# добавляем задания в пул
futs = []
for x in range(POOL_TASK_CHUNK):
if queue.qsize() is 0:
break
# увеличиваем счётчик пулла
count += 1
# пробуем взять задание
try:
task = queue.get()
except:
break
else:
# задание в пул
fut = pool.submit(engine, task)
del task
# для отчёта
futs.append(fut)
print('Submited {} tasks into pool'.format(len(futs)))
# смотрим result'ы работы пула
for fut in futs:
try:
box = fut.result()
except Exception as ex:
print('exception: {}'.format(ex))
else:
# удаляем использованный таск чтобы очистить память
del box
wow = 1
del futs
print("круг: {} finished".format(it))
# ждём когда пулл всё выполнит
while True:
if len(pool._pending_work_items) is not 0:
time.sleep(1)
else:
break
print("pool finished")
print("попробуйте теперь собрать мусор через gc.collect() и память не высвободится")
pdb.set_trace()
if __name__ == '__main__':
main_run(q)