我的任务定义已配置这些限制:
"cpu": "1024",
"memory": "8192"
我正在使用 "docker" 控制组标志在 Docker 容器内运行 jar 文件:
java -XX:+UseContainerSupport -XX:MaxRAMPercentage=80 -XX:InitialRAMPercentage=70 /myjar.jar foo.Main
但 ECS 通过 OOM 错误导致我的服务出现问题。
我已经测量了 JVM 的内存使用情况,并通过以下调试措施在应用程序中报告:
val bean: MemoryMXBean = ManagementFactory.getMemoryMXBean
val hmu: MemoryUsage = bean.getHeapMemoryUsage
val nhu = bean.getNonHeapMemoryUsage
... reporting these metrics ...
在这张图片中,顶部显示的是 CloudWatch 报告的已使用内存情况。正如您所看到的,它已经达到了100%。
底部的图表显示的是应用程序报告的内存使用情况。
val pc = (1.0 * hmu.getUsed) / hmu.getCommitted
根据文档:
* Below is a picture showing an example of a memory pool:
*
* <pre>
* +----------------------------------------------+
* +//////////////// | +
* +//////////////// | +
* +----------------------------------------------+
*
* |--------|
* init
* |---------------|
* used
* |---------------------------|
* committed
* |----------------------------------------------|
* max
/**
* Returns the amount of memory in bytes that is committed for
* the Java virtual machine to use. This amount of memory is
* guaranteed for the Java virtual machine to use.
*
* @return the amount of committed memory in bytes.
*
*/
public long getCommitted() {
return committed;
};
/**
* Returns the amount of used memory in bytes.
*
* @return the amount of used memory in bytes.
*
*/
public long getUsed() {
return used;
};
我的Docker文件非常简单:
FROM openjdk:10-jdk
COPY service.jar /affinity-service.jar
COPY start.sh /start.sh
RUN chmod +x /start.sh
CMD ["/start.sh"]
而start.sh
是:
#!/bin/bash
set -x
OPTS=""
#... setting flags from ENV values...
#...
#...
java -XX:+UseContainerSupport -XX:MaxRAMPercentage=80 -XX:InitialRAMPercentage=70 ${OPTS} -jar /service.jar com.....Service
-XX:+UseContainerSupport -XX:MaxRAMPercentage=80 -XX:InitialRAMPercentage=70
分配的内存似乎超过了容器限制允许的内存。 - AvbaMaxRAMPercentage
无法读取容器限制并获取主机 RAM。参见 https://ops.tips/blog/why-top-inside-container-wrong-memory/。 - Tilo