【问题标题】:How to prevent a Spring Boot / Tomcat (Java8) process be OOM-killed?如何防止 Spring Boot / Tomcat (Java8) 进程被 OOM 杀死?
【发布时间】:2018-07-13 17:57:29
【问题描述】:

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

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

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

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

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

【问题讨论】:

    标签: java linux tomcat


    【解决方案1】:

    首先检查 oomkill 没有被系统中的另一个进程触发,或者服务器没有被其他进程超载。当其他一些贪婪进程是罪魁祸首时,可能是 Tomcat 被 oomkill 不公平地针对。

    堆的最大尺寸 (-Xmx) 应设置为小于服务器上的物理 RAM。如果超过这个,那么分页会导致垃圾收集时性能极差。

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

    运行您的应用程序并它崩溃之前(当然不容易,但您需要判断它),kill -3 tomcat 进程。然后分析堆并尝试找出元空间变大的原因。它通常是由动态加载类引起的。这是您的应用程序正在做的事情吗?更有可能的是,它是一些框架这样做。 (nb oom Killer 会杀死 -9 的 tomcat 进程,之后你将无法进行诊断,所以你需要让应用运行并在此发生之前进行干预)。

    也看看这个问题 - 有一个有趣的答案声称对 XML 绑定设置的模糊修复清除了问题(非常有问题但可能值得一试)java8 "java.lang.OutOfMemoryError: Metaspace"

    【讨论】:

      【解决方案2】:

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

      所以步骤获得了巨大的改进(如果你可以转移到 Spring Boot 应用程序):

      • 迁移到 Spring Boot 应用程序。就我而言,这需要 3 个简单的操作。
      • 使用轻量级基础映像。见下文。
      • 非常重要 - 使用 Java 内存平衡选项。请参阅下面 Dockerfile 的最后一行。这将我正在运行的容器 RAM 使用量从超过 650MB 减少到 ONLY 240MB。运行平稳。所以,在 650MB 上SAVING超过 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"]
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-01-18
        • 2019-12-25
        • 2012-03-07
        • 1970-01-01
        • 2020-05-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多