Java 多处理Jpype中的内存泄漏

Java 多处理Jpype中的内存泄漏,java,python,jpype,Java,Python,Jpype,我有一个python代码,它通过jpype使用java库。目前,每次运行我的函数都会检查JVM是否存在,如果不存在,则创建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) 此外,我想使用pytho

我有一个python代码,它通过jpype使用java库。目前,每次运行我的函数都会检查JVM是否存在,如果不存在,则创建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
时,内存仍然会随着时间的推移而累积,这是不可取的。这个过程非常简单,建议通过使用
jp.attachThreadToJVM
jp.detachThreadToJVM
包装python线程来同步线程。然而,我在网上找不到一个关于如何真正做到这一点的例子。我曾尝试用这些语句将函数
dou\u hard
封装在
myfunc
中,但对泄漏没有任何影响。我还尝试在
myfunc
结束时使用
jp.shutdownJVM
显式关闭JVM。然而,在本例中,当我有超过1个内核时,JVM似乎就会崩溃,这使我相信存在竞争条件

请帮助:

  • 发生了什么事?为什么会有比赛条件?不是每个线程都有自己的JVM吗
  • 在我的场景中,释放内存的正确方法是什么

    • 问题在于多处理的本质。Python可以派生或生成新进程。fork选项似乎与JVM有很大的问题。linux上的默认值是fork

      使用spawn上下文(multiprocessing.get_context(“spawn”)创建Python的派生版本将允许创建新的JVM。每个派生副本都是完全独立的。github上测试目录中的subrun.py中有一些示例,因为这是用于测试JPype的不同JVM选项的

      fork版本创建原始进程的副本,包括以前运行的JVM。至少在我的测试中,分叉的JVM没有像预期的那样工作。较旧版本的JPype(0.6.x)将允许分叉版本调用startJVM,这将造成较大的内存泄漏。当前版本0.7.1给出了一个异常,JVM无法重新启动

      如果您使用的是线程(而不是进程),那么所有线程都共享同一个JVM,不需要单独访问JVM。在github的最新文档中的“限制”部分有关于使用JPype进行多处理的更多文档