我可以在OOM上的JVM调用的脚本中使用“ kill%p”吗?

时间:2019-07-17 16:48:13

标签: java shell gradle jvm jvm-arguments

我仍然准备对此进行测试,但是在继续之前,我需要一些输入。我正在使用Gradle在JVM中设置内存不足的处理。其中一部分涉及创建重新启动脚本,以通过JVM选项在OOM上调用。

它的工作方式是我先

task appStartScripts(type: CreateStartScripts) {
    def tplName = 'startBinTemplate.sh'
    assert project.file(tplName).exists()
    unixStartScriptGenerator.template = resources.text.fromFile(tplName)
    defaultJvmOpts = [
                      "-XX:+HeapDumpOnOutOfMemoryError",
                      "-XX:HeapDumpPath=\$HOME/apps/log/",
                      "-XX:OnOutOfMemoryError=./restart.sh",

                      "-Xms1G", "-Xmx2G",
                      "-Dapp.name=${rootProject.name}"]

    dependsOn shadowJar
    applicationName = 'start'
    defaultJvmOpts += ["-Dspring.profiles.active=ENV_VARIABLE"]
    classpath = startShadowScripts.classpath
    mainClassName = startShadowScripts.mainClassName
    outputDir = new File(project.buildDir, 'scriptsShadow')

    doLast {
        unixScript.text = unixScript.text.replace('\\$HOME', '\'"$HOME"\'')
        unixScript.text = unixScript.text.replace('ENV_VARIABLE', '\'"$1"\'')
    }
}

理论上,在发生内存不足错误时,重新启动脚本将被称为:

#!/usr/bin/env sh

kill -9 %p
sleep 5
./start.sh

这将终止该进程,休眠5秒钟,然后使用启动脚本重新启动它。我的问题是关于杀死的%p参数。我可以在这种情况下在脚本中使用它,而不是使用JVM参数本身吗?我的理解是应该将其传递给JVM参数,然后它将使用该参数传递服务PID以终止服务。就我而言,我在脚本中使用它是因为尝试将kill -9 %p传递给$ JVM_ARGS会导致启动时出错:

Unrecognized option: -9

传入要调用的脚本似乎不会引起任何问题。

我仍在为此设置测试用例,但我想问一下:

  1. 有人这样做吗?您的经历是什么?
  2. 我有更好的方法来解决这个问题吗?

1 个答案:

答案 0 :(得分:0)

%p占位符在执行OnOutOfMemoryError时由JVM解析。您将必须在命令-XX:OnOutOfMemoryError=./restart.sh %p中使用,然后从$1中的restart.sh中读取它。

现代JVM具有ExitOnOutOfMemoryError选项,其行为与OnOutOfMemoryError="kill -9 %p"相同(请参见JDK-8152669)。您可以将其与显示在in this answer上的bash脚本结合使用:

#!/bin/sh

while true ; do
  java -XX:+ExitOnOutOfMemoryError -jar application.jar
  sleep 5
done