Утечки памяти в Jpype с многопроцессорностью - PullRequest
0 голосов
/ 04 ноября 2019

У меня есть код 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?
  • Как правильно освободить память в моем сценарии?
...