首页 > 解决方案 > 如何防止 Spring Boot / Tomcat (Java8) 进程被 OOM 杀死?

问题描述

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

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

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

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

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

标签: javalinuxtomcat

解决方案


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

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

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

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

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


推荐阅读