卸载rJava和/或重新启动JVM

Jer*_*oen 12 java jvm r cran rjava

我想rJava结合使用,mcparallel但显然JVM不能分叉.因此,需要为每个子进程启动单独的JVM实例,例如:

library(rJava)
library(parallel)
myfile <-  system.file("tests", "test_import.xlsx", package = "xlsx")

#This works:
mccollect(mcparallel({
  #Automatically initiates JVM in child
  xlsx::read.xlsx(myfile, 1)
}))
Run Code Online (Sandbox Code Playgroud)

但是我的问题是JVM已经在(主)父进程中启动了.这使得无法rJava在子进程中使用:

#init JVM in parent
.jinit()

#Doesn't work anymore
mccollect(mcparallel({
  xlsx::read.xlsx(myfile, 1)
}))
Run Code Online (Sandbox Code Playgroud)

所以我真正需要的是在子进程中关闭/终止和重启JVM的方法.只是 detach("package:rJava", unload = TRUE)似乎没有这样的伎俩.该force.init参数似乎不会导致重启:

#Also doesn't work:
.jinit()
mccollect(mcparallel({
  .jinit(force.init = TRUE)
  xlsx::read.xlsx(myfile, 1)
}))
Run Code Online (Sandbox Code Playgroud)

有没有什么方法可以强制关闭/杀死JVM以便在子进程中重新启动它?

Pet*_*usu 1

有一种方法可以使用 rJava 并行运行表达式,该方法基于运行并行进程来在主进程中加载​​ rJava 库之前获取并组装所有结果。由于主 R 进程尚未启动 jvm,因此 java 在每个子进程中启动,并且该特定实例也将与子进程一起死亡。

# Rsession started
library(parallel)
myfile <-  system.file("tests", "test_import.xlsx", package = "xlsx")
e <- expression({
require(rJava)
require(xlsx)
read.xlsx(myfile, 1)
})
p <- mcparallel(e)
q <- mcparallel(e)
pq <- mccollect(list(p, q))

# again to check reproducibility
p <- mcparallel(e)
q <- mcparallel(e)
pq2 <- mccollect(list(p, q))
identical(unname(pq),unname(pq2))

# see the result if it is the right content and not tryerr
pq

# now the main continues ...
# and if necessary even load rJava
Run Code Online (Sandbox Code Playgroud)