我正在泄漏jRuby进程,我不知道如何阻止它。我需要groovy脚本在启动jRuby之后继续运行,当主脚本死亡时我需要jRuby死。
test.groovy
,loop.rb
loop.rb
while( true )
puts 'Hello from jRuby'
sleep 1
end
test.groovy
def command = "jruby ./loop.rb"
Thread.start {
Process process
try {
process = command.execute()
}
catch (IOException e) {
e.printStackTrace()
return
}
Runtime.runtime.addShutdownHook {
println "Attempting to stop process"
process.destroy()
}
process.consumeProcessOutput(System.out, System.err)
process.waitFor()
}
while( true ){ println 'Hello from groovy'; Thread.sleep(1000) }
执行
groovy test.groovy
如何确保使用jRuby创建的外部javaw
进程被终止?尽管将Cntrl+C
发送到正在运行的应用程序会导致正在运行的groovy进程,但jRuby进程仍然存在。帮助
答案 0 :(得分:0)
这应该可以解决问题,但这很难看:
基本解决方案是查看jps -lm
的输出并从其中列出的PID中删除相应的进程。
new JavaProcessKiller().killAll('loop.rb')
class JavaProcessKiller {
public void killAll(String processPattern) {
getRunningJavaProcesses().each { String processLine ->
if (processLine.contains(processPattern)) {
String pidToKill = getPidFromProcessLine(processLine)
killPid(pidToKill)
}
}
}
protected String[] getRunningJavaProcesses() {
def output = new ByteArrayOutputStream()
def p = ['jps', '-lm'].execute()
p.consumeProcessOutput(new PrintStream(output), System.err)
p.waitFor()
return output.toString().split("\\n")
}
protected String getPidFromProcessLine(String line) {
def pidPattern = /^(\d+).*$/
def matcher = (line =~ pidPattern)
return matcher[0][1]
}
protected void killPid(String pid) {
def killCommands = [
['taskkill', '/F', '/PID', pid],
['kill', pid]
]
boolean processKilledSuccessfully = false
killCommands.each { command ->
if (!processKilledSuccessfully) {
try {
def output = new ByteArrayOutputStream()
def error = new ByteArrayOutputStream()
def process = command.execute()
process.consumeProcessOutput(new PrintStream(output), new PrintStream(error))
process.waitFor()
processKilledSuccessfully = true
}
catch (Exception e) {
}
}
}
}
}