如何防止Spring Boot / Tomcat(Java8)进程被OOM杀死?

时间:2018-07-13 17:57:30

标签: java linux tomcat

自从迁移到Tomcat8 / Java8以来,Tomcat服务器有时会被OOM杀死。 OOM = Linux内核杀死内存不足。

如何防止Tomcat服务器被OOM杀死?

这可能是内存泄漏的结果吗?我想我会收到一条正常的内存不足消息,但是没有OOM杀伤力。正确?

我应该更改HEAP大小的设置吗? 我应该更改MetaSpace大小的设置吗?

知道哪个Tomcat进程被杀死了,如何获取信息,以便我可以重新配置Tomcat服务器?

2 个答案:

答案 0 :(得分:2)

首先检查oomkill是否未被系统中的另一个进程触发,或者服务器是否没有其他进程过载。当其他一些贪婪的过程是罪魁祸首时,可能是oomkill不公正地将Tomcat作为攻击目标。

应将堆设置为最大大小(-Xmx),以使其小于服务器上的物理RAM。如果不止如此,那么分页将导致垃圾回收时性能严重下降。

如果这是由于元空间以无限增长的方式引起的,那么您需要找出原因。一旦达到设置的限制,简单地设置元空间的最大大小将导致内存不足错误。而且提高限制将毫无意义,因为最终您将达到设置的任何更高限制。

运行您的应用程序,然后之前崩溃(当然不容易,但是您需要对其进行判断),杀死-3 tomcat进程。然后分析堆并尝试找出为什么元空间变得越来越大。通常是由动态加载类引起的。这是您的应用程序正在执行的操作吗?更有可能是由某些框架来完成的。 (Nb oom杀手会杀死-9的tomcat进程,在那之后您将无法进行诊断,因此您需要让该应用运行并进行干预)。

还请查看此问题-有一个有趣的答案,声称对XML绑定设置的模糊修复可以解决问题(高度可疑,但值得尝试)java8 "java.lang.OutOfMemoryError: Metaspace"

答案 1 :(得分:1)

另一个非常好的解决方案是将您的应用程序转换为Spring Boot JAR(Docker)应用程序。通常,此应用程序的内存消耗要少得多。

因此,可以进行重大改进(如果您可以移至Spring Boot应用程序):

  • 迁移到Spring Boot应用程序。就我而言,这仅需执行3个简单的操作即可。
  • 使用重量轻的基本图像。见下文。
  • 非常重要-使用Java内存平衡选项。请参阅下面的Dockerfile的最后一行。这将我正在运行的容器RAM使用量从650MB以上减少到了 240MB。运行平稳。因此,在650MB上节省了超过400MB!

这是我的Dockerfile:

FROM openjdk:8-jdk-alpine
ENV JAVA_APP_JAR your.jar
ENV AB_OFF true
EXPOSE 8080
ADD target/$JAVA_APP_JAR /deployments/
CMD ["java","-XX:+UnlockExperimentalVMOptions", "-XX:+UseCGroupMemoryLimitForHeap", "-jar","/deployments/your.jar"]