解决 k8s 限制内存后 还出现 OOM 错误的问题:资源整合
如果应用所使用的 java 版本在 8及8以下, JVM 在没有认为设定 Xmx Xms 时, 会根据 宿主机的内存进行 JVM 的参数设置,这样就会导致很大的问题。比如,如果你的宿主机内存在 8G, 你的容器设置为 1G,那么 JVM 根据你的宿主机内存,给到你应用 2G左右的堆内存,此时 JVM 会按照 2G 进行 GC,此时会出现 OOM ,而导致容器被 kill 的情况。这一...
如果应用所使用的 java 版本在 8及8以下, JVM 在没有认为设定 Xmx Xms 时, 会根据 宿主机的内存进行 JVM 的参数设置,这样就会导致很大的问题。
比如,如果你的宿主机内存在 8G, 你的容器设置为 1G,那么 JVM 根据你的宿主机内存,给到你应用 2G左右的堆内存,此时 JVM 会按照 2G 进行 GC,此时会出现 OOM ,而导致容器被 kill 的情况。
这一情况在此篇博客中有详细探讨:
《Kubernetes之路 1 - Java应用资源限制的迷思》
https://blog.csdn.net/maoreyou/article/details/80134303
解决办法有三种:
一、 手动指定 应用启动时的 JVM 参数:
JVM的参数指定可以参考这几篇文章:
1、 根据这篇中的参数进行初步设定
《关于JVM突破Docker内存限制的解决方案及JVM推荐配置》
https://blog.csdn.net/cy_7030/article/details/81536590
2、 根据这篇中的 JVM 参数调优方法,参考实际应用,重新调整 JVM 值:
《JVM内存设置多大合适?Xmx和Xmn如何设置?》
https://www.cnblogs.com/zhangfengshi/p/11343102.html
《JVM 调优总结》
https://www.cnblogs.com/diegodu/p/9849611.html
《 jstat命令查看jvm的GC情况 (以Linux为例)》
https://www.cnblogs.com/yjd_hycf_space/p/7755633.html
《jvm 性能调优工具之 jmap》
https://www.jianshu.com/p/a4ad53179df3
还需要注意: 如果你的 Docker 中启动 java 使用的是 sh 而非 /bin/bash ,java进程的 pid 是1,
会导致:
Unable to get pid of LinuxThreads manager thread
通过使用 /bin/bash 启动可以解决:
《jstack on alpine:Unable to get pid of LinuxThreads manager thread》
https://blog.csdn.net/xianzi1261618338/article/details/83382989
二、 使用 java9 及以上版本,使用 容器资源感知特性:
java -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap …
三、 使用这位大神制作的 tomcat 8 自动感知 CGroup 的镜像:
参考:
《如何设置Docker容器中Java应用的内存限制》
更多推荐
所有评论(0)