【问题标题】:How do I stop leaking javaw processes when running jRuby in a thread?在线程中运行 jRuby 时如何停止泄漏 javaw 进程?
【发布时间】:2011-08-20 01:21:47
【问题描述】:

我正在泄漏 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 进程仍然存在。帮忙?

【问题讨论】:

  • 它实际上并没有杀死进程。
  • 如果是 windows,我不得不求助于调用 taskkill,就像接受的答案一样(jruby 的 Process.kill 也不起作用)
  • 更新:jruby 的 Process.kill 现在可以在 windows 中工作了 :)

标签: ruby groovy process jvm jruby


【解决方案1】:

这应该可以解决问题,但它很丑:

基本的解决方案是查看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) {
                }
            }
        }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-11-15
    • 1970-01-01
    • 1970-01-01
    • 2018-09-26
    • 2015-12-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多