繁体   English   中英

Memory 在 Jpype 中通过多处理泄漏

[英]Memory leaks in Jpype with multiprocessing

我有一个 python 代码,它通过 jpype 使用 java 库。 目前,我的 function 的每次运行都会检查 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 多处理库并行化我的代码。 每个线程(据说)独立工作,用不同的参数计算我的 function 的值。 例如

import pathos

pool = pathos.multiprocessing.ProcessingPool(8)
params = np.arange(100)
result = pool.map(myfunc, params)

这种结构工作正常,但在池中使用超过 1 个核心时,它会出现严重的 memory 泄漏。 我注意到,当 python 关闭时,所有 memory 都已释放,但 memory 仍会随着时间的推移而累积,而pool.map jpype 文档非常简短,建议通过使用jp.attachThreadToJVMjp.detachThreadToJVM包装 python 线程来同步线程。 但是,我无法在网上找到一个关于如何实际操作的示例。 我尝试使用这些语句将 function do_something_hard包装在myfunc中,但它对泄漏没有影响。 我还尝试使用 jp.shutdownJVM 在myfunc末尾显式关闭jp.shutdownJVM 但是,在这种情况下,JVM 似乎在我拥有超过 1 个内核时立即崩溃,这让我相信存在竞争条件。

请帮忙:

  • 到底是怎么回事? 为什么会有竞态条件? 不是这样吗,每个线程都有自己的 JVM?
  • 在我的场景中释放 memory 的正确方法是什么?

问题在于多处理的性质。 Python 可以分叉或生成一个新进程。 对于 JVM,fork 选项似乎存在重大问题。 linux 上的默认值为 fork。

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

fork 版本创建原始进程的副本,包括先前运行的 JVM。 至少从我的测试来看,分叉的 JVM 没有按预期工作。 较早版本的 JPype (0.6.x) 将允许分叉版本调用 startJVM,这会造成大的 memory 泄漏。 当前版本 0.7.1 给出了 JVM 无法重新启动的例外情况。

如果您使用线程(而不是进程),则所有线程共享相同的 JVM,并且不需要单独使用 JVM。 在 github 的“限制”部分下的最新文档中,有更多关于使用 JPype 进行多处理的文档。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM