У меня есть код Python, который использует библиотеку Java с помощью jpype. В настоящее время каждый запуск моей функции проверяет, существует ли JVM, и создает его, если это не так
import jpype as jp
def myfunc(i):
if not jp.isJVMStarted():
jp.startJVM(jp.getDefaultJVMPath(), '-ea', ('-Djava.class.path=' + jar_location))
do_something_hard(i)
Далее, я хочу распараллелить мой код, используя многопроцессорную библиотеку python. Каждый поток (предположительно) работает независимо, вычисляя значение моей функции с разными параметрами. Например,
import pathos
pool = pathos.multiprocessing.ProcessingPool(8)
params = np.arange(100)
result = pool.map(myfunc, params)
Эта конструкция отлично работает, за исключением того, что она имеет значительные утечки памяти при использовании более одного ядра в пуле. Я заметил, что вся память освобождается, когда python закрыт, но память все еще накапливается с течением времени, пока работает pool.map
, что нежелательно. Документация jpype невероятно кратка, предлагая синхронизировать потоки, оборачивая потоки python в jp.attachThreadToJVM
и jp.detachThreadToJVM
. Тем не менее, я не могу найти ни одного примера в Интернете о том, как на самом деле это сделать. Я попытался обернуть функцию do_something_hard
внутри myfunc
этими утверждениями, но это не повлияло на утечку. Я также пытался явно закрыть JVM в конце myfunc
, используя jp.shutdownJVM
. Однако в этом случае JVM, похоже, дает сбой, как только у меня появляется более 1 ядра, что наводит меня на мысль о наличии состояния гонки.
Пожалуйста, помогите:
- Что такоепродолжается? Почему бы возникли условия гонки? Разве это не тот случай, когда каждый поток создает свою собственную JVM?
- Как правильно освободить память в моем сценарии?