Docker 容器内 Java 应用发生 OutOfMemoryError 堆内存空间不足时, 容器无法重启应用
背景
在一次生产环境部署 elasticsearch 节点时 docker 容器设置了 –restart always,
此时 elasticsearch 的一个节点发生了 java.lang.OutOfMemoryError: Java heap space
容器并没有重启
elasticsearch 已经设置了 -Xms -Xmx
解释
JVM堆内存超出xmx限制,并抛java.lang.OutOfMemoryError: Java heap space异常。堆内存爆了之后,JVM和java进程会继续运行,并不会crash
解决
当JVM出现 OutOfMemoryError,要让 JVM 自行退出, 这样容器就会触发重启
添加新的 jvm 配置: ExitOnOutOfMemoryError and CrashOnOutOfMemoryError
该配置支持 jdk8u92 版本及其之后的版本
地址: https://www.oracle.com/technetwork/java/javase/8u92-relnotes-2949471.html
oracle 官网的原话:
New JVM Options added: ExitOnOutOfMemoryError and CrashOnOutOfMemoryError
Two new JVM flags have been added:
ExitOnOutOfMemoryError - When you enable this option, the JVM exits on the first occurrence of an out-of-memory error. It can be used if you prefer restarting an instance of the JVM rather than handling out of memory errors.
CrashOnOutOfMemoryError - If this option is enabled, when an out-of-memory error occurs, the JVM crashes and produces text and binary crash files (if core files are enabled).
ExitOnOutOfMemoryError: 启用此选项时,JVM在第一次出现内存不足错误时退出。如果您希望重新启动JVM实例而不是处理内存不足错误,则可以使用它。
CrashOnOutOfMemoryError: 如果启用此选项,则在发生内存不足错误时,JVM崩溃并生成文本和二进制崩溃文件(如果启用了核心文件)。
加上配置
ES_JAVA_OPTS = “-XX:+ExitOnOutOfMemoryError”