Я видел пару сообщений об использовании памяти, используя модуль Pipon Multiprocessing. Однако вопросы, кажется, не отвечают на проблему, которую я здесь. Я отправляю свой анализ с надеждой, что кто-то может мне помочь.
Проблема
Я использую многопроцессорную обработку для выполнения задач параллельно, и я заметил, что потребление памяти рабочими процессами растет бесконечно. У меня есть небольшой отдельный пример, который должен повторить то, что я замечаю.
import multiprocessing as mp
import time
def calculate(num):
l = [num*num for num in range(num)]
s = sum(l)
del l # delete lists as an option
return s
if __name__ == "__main__":
pool = mp.Pool(processes=2)
time.sleep(5)
print "launching calculation"
num_tasks = 1000
tasks = [pool.apply_async(calculate,(i,)) for i in range(num_tasks)]
for f in tasks:
print f.get(5)
print "calculation finished"
time.sleep(10)
print "closing pool"
pool.close()
print "closed pool"
print "joining pool"
pool.join()
print "joined pool"
time.sleep(5)
Система
Я запускаю Windows, и я использую диспетчер задач для контроля использования памяти. Я запускаю Python 2.7.6.
Наблюдение
Я обобщил потребление памяти двумя рабочими процессами ниже.
+---------------+----------------------+----------------------+
| num_tasks | memory with del | memory without del |
| | proc_1 | proc_2 | proc_1 | proc_2 |
+---------------+----------------------+----------------------+
| 1000 | 4884 | 4694 | 4892 | 4952 |
| 5000 | 5588 | 5596 | 6140 | 6268 |
| 10000 | 6528 | 6580 | 6640 | 6644 |
+---------------+----------------------+----------------------+
В приведенной выше таблице я попытался изменить количество задач и понаблюдать за памятью, потребляемой в конце всех вычислений, и до join
-в <<23 > . Параметры "del" и "без del" - это то, что я не комментирую или комментирую строку del l
внутри функции calculate(num)
, соответственно. Перед вычислением потребление памяти составляет около 4400.
- Похоже на то, что вручную очистка списков приводит к снижению использования памяти для рабочих процессов. Я думал, что сборщик мусора позаботился об этом. Есть ли способ принудительного сбора мусора?
- Непонятно, что с увеличением числа задач использование памяти в обоих случаях растет. Есть ли способ ограничить использование памяти?
У меня есть процесс, основанный на этом примере и предназначенный для долгосрочного выполнения. Я наблюдаю, что эти рабочие процессы забивают много памяти (~ 4 ГБ) после ночного прогона. Выполнение join
для освобождения памяти не является опцией, и я пытаюсь найти способ без join
-ing.
Это кажется немного загадочным. Кто-нибудь сталкивался с чем-то похожим? Как я могу исправить эту проблему?