在前文《記一次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內存設置不正確