在前文《记一次OutOfMemory定位过程》完成时最终也没有定位到ECS 中JVM Heap size没法控制的缘由,今天再次尝试终于有了一些线索,翻查了ECS的部署脚本发现了memoryReservation
参数,根据Amazon Elastic Container Service任务定义参数的定义,它对应的是docker run的--memory-reservation
选项,该参数是一个软控制,实限上内存使用是能够超过该限制的,因而把它修改成memory
,同时推送一个新的image并部署html
ENTRYPOINT exec java -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -XX:MaxRAMFraction=1 -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XshowSettings:vm -jar app.jar
task启动后输出,结果以下:java
VM settings: Max. Heap Size (Estimated): 3.56G Ergonomics Machine Class: server Using VM: OpenJDK 64-Bit Server VM
此次的Heap size终于看上去像是想要的,只是不幸的是在程序维持繁忙状态约半小时后,再次由于一样的缘由被关闭docker
Status reason OutOfMemoryError: Container killed due to memory usage Exit Code 137
查看其中一个task最后的GC日志app
2018-06-07T07:57:55.742+0000: [GC (Allocation Failure) [PSYoungGen: 1013313K->121010K(1150464K)] 3324353K->2449342K(3730944K), 0.3680289 secs] [Times: user=0.37 sys=0.04, real=0.36 secs] 2018-06-07T07:58:01.582+0000: [GC (Allocation Failure)
JVM Heap size直到最后都并无超限,也许XX:MaxRAMFraction=2
能够解决这个问题,可是内存使用率又过低,故最终仍是决定使用ide
ENTRYPOINT exec java -Xmx3072m -Xms3072m -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XshowSettings:vm -jar app.jar
把内存使用率控制在75%,运行近三小时没有再出现问题。ui
-XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -XX:MaxRAMFraction=1
时,JVM没法根据Docker容器的内存设置最大Heap size是由于ECS的参数选得不对,致使Docker内存设置不正确