java - 如何使用 -XX:OnOutOfMemoryError= 在 OOM 执行脚本
问题描述
我正在尝试设置一种方法来处理我的应用程序中的内存不足错误。到目前为止,我已将以下选项添加到我的 Gradle 构建文件中:
task appStartScripts(type: CreateStartScripts) {
def tplName = 'startTemplate.sh'
assert project.file(tplName).exists()
defaultJvmOpts = ["-XX:+HeapDumpOnOutOfMemoryError",
"-XX:HeapDumpPath=\$HOME/log/",
"-XX:OnOutOfMemoryError=./\$HOME/application/bin/restart.sh",
"-Xms64m", "-Xmx124m"]
dependsOn shadowJar
applicationName = 'start'
defaultJvmOpts += ["-Dspring.profiles.active=ENV_VARIABLE"]
classpath = startShadowScripts.classpath
mainClassName = startShadowScripts.mainClassName
outputDir = new File(project.buildDir, 'scriptsShadow')
doLast {
// IMPORTANT! needed to ensure HOME environment variable is expanded correctly
unixScript.text = unixScript.text.replace('\\$HOME', '\'"$HOME"\'')
unixScript.text = unixScript.text.replace('ENV_VARIABLE', '\'"$1"\'')
}
其中 XX:OnOutOfMemoryError 在发生内存不足错误时调用重启脚本。在 restart.sh 脚本本身中,我有以下内容:
while true : do
java -XX:+ExitOnOutOfMemoryError -jar application.jar
sleep 5
done
./start.sh
要杀死应用程序,请等待 5 秒,然后在同一目录中调用启动脚本以重新启动应用程序。
为了测试这一点,我在我的一个 get 请求中添加了一个无限循环:
@GET
@Timed
@Path("/{ids}")
public List<Profile> getProfileByID(@PathParam("ids") String ids) {
boolean forever = true;
try {
logger.info("STARTED SERVICE: getProfileID with the following parameters: IDs = {}", ids);
int[] array = idsStringToArray(ids);
List<Profile> profileList = profileManager.getProfiles(array);
List<Integer> myList = new ArrayList<Integer>();
while (forever) {
profileManager.getProfiles(array);
myList.add(1000);
}
logger.info("COMPLETED SERVICE: getProfileID with the following parameters: Ids = {}", ids);
return profileList;
}
myList 将继续向其中添加更多项目,从而消耗内存。
也就是说,我还不能导致错误触发脚本。还有什么我可以做的吗?
此外,这是该服务的 top 命令的结果:
Tasks: 1 total, 0 running, 1 sleeping, 0 stopped, 0 zombie
%Cpu(s): 1.4 us, 1.3 sy, 0.0 ni, 97.3 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 32160180 total, 21291040 free, 4559124 used, 6310016 buff/cache
KiB Swap: 2097148 total, 2097148 free, 0 used. 27127132 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
30504 user1 20 0 3778748 371724 18048 S 4.0 1.2 3:50.33 java
编辑:我只是尝试直接在代码中调用 OOM 错误,但它只是抛出异常而没有别的:
@GET
@Timed
@Path("/{ids}")
public List<Profile> getProfileByID(@PathParam("ids") String ids) {
boolean forever = true;
try {
logger.info("STARTED SERVICE: getProfileID with the following parameters: IDs = {}", ids);
int[] array = idsStringToArray(ids);
List<Profile> profileList = profileManager.getProfiles(array);
throw new OutOfMemoryError();
}
解决方案
我能够引发错误。我通过比以前更多地降低堆空间来做到这一点:
"-Xms64m", "-Xmx124m",
并通过让我的 get 方法生成一个 long 数组 l:
@GET
@Timed
@Path("/{ids}")
public List<Profile> getProfileByID(@PathParam("ids") String ids) {
boolean forever = true;
try {
logger.info("STARTED SERVICE: getProfileID with the following parameters: IDs = {}", ids);
int[] array = idsStringToArray(ids);
List<Profile> profileList = profileManager.getProfiles(array);
long[] l = new long[Integer.MAX_VALUE];
推荐阅读
- protractor - 如何在量角器中的单个描述中使用多个数据提供者
- ios - SQLite从JSON对象ios插入多行
- excel - 如果满足条件,则复制和粘贴数据
- amazon-web-services - AWS 在使用 SDK 时承担角色访问被拒绝
- python-3.x - 将上下文菜单添加到特定的 Qtablewdiget 表列,Python
- python - 蛇动画
- wso2 - WSO2 ESB/EI:如何将原始 JSON 正文转换为 XML 有效负载
- javascript - 如何从服务器的子文件夹中使用 socket.io?
- javascript - 如何在 Typescript 和 React.js 中使用随机字段解析 JSON
- powerbi - 使用 DAX 在 Power Bi 中计算文本函数中的错误