簡體   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