由于迁移到Tomcat8/Java8,Tomcat服务器有时会被OOM杀死。OOM=Linux内核导致内存不足。
如何防止Tomcat服务器被OOM杀死
这可能是内存泄漏的结果吗?我想我会得到一个正常的内存不足消息,但没有OOM杀死。对的
我应该更改HEAP大小的设置吗?我应该更改MetaSpace大小的设置吗?
知道哪个Tomcat进程被终止,如何检索信息以便重新配置Tomcat服务器?
首先检查oomkill是否由系统中的另一个进程触发,或者服务器是否被其他进程过载。这可能是Tomcat被oomkill不公平地盯上了,而其他贪婪的进程才是罪魁祸首。
堆应该设置为最大大小(-Xmx(,以小于服务器上的物理RAM。如果超过这个数量,那么分页将导致垃圾收集时性能极差。
如果这是由元空间以无限的方式增长引起的,那么你需要找出为什么会发生这种情况。只要简单地设置元空间的最大大小,一旦达到您设置的限制,就会导致内存不足错误。提高限制是毫无意义的,因为最终你会达到你设定的任何更高的限制。
在崩溃之前运行您的应用程序并(当然不容易,但您需要判断它(,杀死-3 tomcat进程。然后分析这个堆,试图找出元空间为什么越来越大。它通常是由动态加载类引起的。这是你的应用程序正在做的事情吗?更有可能的是,这是某种框架在做这件事。(Nb oom杀手会杀死-9 tomcat进程,之后你将无法进行诊断,所以你需要让应用程序运行并在发生这种情况之前进行干预(。
还可以看看这个问题——有一个有趣的答案,它声称对XML绑定设置的模糊修复解决了问题(非常值得怀疑,但可能值得一试(java8";java.lang.OutOfMemoryError:Metaspace">
另一个非常好的解决方案是将您的应用程序转换为Spring Boot JAR(Docker(应用程序。通常情况下,此应用程序的内存消耗要少得多。
因此,步骤得到了巨大的改进(如果你可以转移到Spring Boot应用程序(:
- 迁移到Spring Boot应用程序。就我而言,这需要3个简单的操作
- 使用轻量级的基础图像。请参见下文
- 非常重要-使用Java内存平衡选项。请参阅下面Dockerfile的最后一行。这将我的运行容器RAM使用量从超过650MB减少到ONLY240MB。运行平稳。因此,在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"]