我有Java应用程序,包装在Docker中并托管在Amazon ECS上。
主要技术是:
每1-2天,应用程序崩溃,并被亚马逊服务重新唤醒。
在Docker昆虫的驱使下,我找到了原因:
"OOMKilled": true,
我已将执行器连接到CloudWatch,并且发现内存消耗曲线有奇怪的行为:
那些蓝色的峰值是应用程序崩溃的时刻。
我已经了解到Java 8在正确读取主机的最大内存方面存在一些问题,但是:
1)Docker从应该解决问题的标志开始
ENTRYPOINT exec java -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -XX:MaxRAMFraction=1 -Xms300M -XX:PermSize100M -Djava.security.egd=file:/dev/./urandom -jar /app.jar
2)无论如何,VM具有4Gb内存,因此〜1.3Gb峰值很高,不应杀死应用程序。
3)高峰时服务器上没有任何负载
答案 0 :(得分:1)
-XX:PermSize100M
不适用于Java 8。
-XX:MaxRAMFraction = 1
这告诉JVM, java对象的托管堆的最大值是所有可用内存。但是JVM分配的内存不仅仅是为Java对象分配的。例如。元空间,打开文件的字节缓冲区,已加载的本机库等。
您应该执行以下操作之一:
MaxRAMFraction=2
代替1 Xmx
设置为低于可用内存的值MaxRAMPercentage
进行更细粒度的控制有关更新的Java版本的其他信息,另请参见"Is -XX:MaxRAMFraction=1 safe for production in a containered environment?"。