[英]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.attachThreadToJVM
和jp.detachThreadToJVM
包裝 python 線程來同步線程。 但是,我無法在網上找到一個關於如何實際操作的示例。 我嘗試使用這些語句將 function do_something_hard
包裝在myfunc
中,但它對泄漏沒有影響。 我還嘗試使用 jp.shutdownJVM 在myfunc
末尾顯式關閉jp.shutdownJVM
。 但是,在這種情況下,JVM 似乎在我擁有超過 1 個內核時立即崩潰,這讓我相信存在競爭條件。
請幫忙:
問題在於多處理的性質。 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.