我可以在 OOM 上由 JVM 调用的脚本中使用 "kill %p"
Can I use "kill %p" in a script being called by JVM on OOM
我仍在准备对此进行测试,但在我继续之前我需要一些输入。我正在 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', '\'""\'')
}
}
理论上,在出现内存不足错误时,将调用重启脚本:
#!/usr/bin/env sh
kill -9 %p
sleep 5
./start.sh
这将杀死进程,休眠 5 秒,然后使用启动脚本重新启动它。我的问题是关于 kill 的 %p
参数。我可以在此上下文中的脚本中使用它,而不是 JVM 参数本身吗?我的理解是,它应该传递给 JVM 参数,然后 JVM 参数将使用它传递服务 PID 以终止服务。就我而言,我在脚本中使用它,因为试图将 kill -9 %p
传递给 $JVM_ARGS 会导致启动时出错:
Unrecognized option: -9
而传入要调用的脚本似乎不会引起任何问题。
我还在为此设置测试用例,但我想问:
- 有人做过吗?您的体验如何?
- 我有没有更好的方法来解决这个错误?
%p
占位符在执行 OnOutOfMemoryError
时由 JVM 解析。您必须在命令中使用 -XX:OnOutOfMemoryError=./restart.sh %p
,然后在 restart.sh
.
中从 </code> 读取它
<p>现代 JVM 具有 <code>ExitOnOutOfMemoryError
选项,其行为与 OnOutOfMemoryError="kill -9 %p"
相同(参见 JDK-8152669). You can combine this with a bash script shown in this answer:
#!/bin/sh
while true ; do
java -XX:+ExitOnOutOfMemoryError -jar application.jar
sleep 5
done
我仍在准备对此进行测试,但在我继续之前我需要一些输入。我正在 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', '\'""\'')
}
}
理论上,在出现内存不足错误时,将调用重启脚本:
#!/usr/bin/env sh
kill -9 %p
sleep 5
./start.sh
这将杀死进程,休眠 5 秒,然后使用启动脚本重新启动它。我的问题是关于 kill 的 %p
参数。我可以在此上下文中的脚本中使用它,而不是 JVM 参数本身吗?我的理解是,它应该传递给 JVM 参数,然后 JVM 参数将使用它传递服务 PID 以终止服务。就我而言,我在脚本中使用它,因为试图将 kill -9 %p
传递给 $JVM_ARGS 会导致启动时出错:
Unrecognized option: -9
而传入要调用的脚本似乎不会引起任何问题。
我还在为此设置测试用例,但我想问:
- 有人做过吗?您的体验如何?
- 我有没有更好的方法来解决这个错误?
%p
占位符在执行 OnOutOfMemoryError
时由 JVM 解析。您必须在命令中使用 -XX:OnOutOfMemoryError=./restart.sh %p
,然后在 restart.sh
.
</code> 读取它
<p>现代 JVM 具有 <code>ExitOnOutOfMemoryError
选项,其行为与 OnOutOfMemoryError="kill -9 %p"
相同(参见 JDK-8152669). You can combine this with a bash script shown in this answer:
#!/bin/sh
while true ; do
java -XX:+ExitOnOutOfMemoryError -jar application.jar
sleep 5
done