我有一个带有 SpringBoot 版本 2.1.1.RELEASE 的 Java 应用程序(oracle JDK 8u191),我遇到了奇怪的内存使用情况(不认为这与 spring 相关)。
应用程序提供的 HEAP 和 NONHEAP 值的总和远低于 Docker 报告的实际内存使用情况。
我知道 Java 具有除 HEAP 和 NONHEAP 之外的其他内存区域,但我不知道如何衡量它们以及当前行为是否正常。
目前,我的应用程序报告以下内容(在生产中运行 3 天后):
Init Used Committed Max
HEAP: 250M 79M 250M 800M
NONHEAP: 2M 192M 201M 0M
Run Code Online (Sandbox Code Playgroud)
/metricsspringBoot的执行器端点报告相同的内存使用情况。
但是 docker stats 命令报告了这一点(容器内部smem报告了与 java 进程相同的值):
MEM USAGE / LIMIT
750.2MiB / 1.172GiB
Run Code Online (Sandbox Code Playgroud)
堆+非堆和当前使用的内存的区别是299,2mb。
在我们第一次将这项服务投入生产时,我没想到会有 300mb,这导致了很多 OOM,直到我们找到了正确的配置。
即使在 GC 之后,这种“未注册的内存使用量”似乎只会增加而不会减少。
如果我重新启动应用程序,堆+非堆与实际使用之间的差异约为 100mb。
我的 Dockerfile 以这种方式启动应用程序:
ENTRYPOINT ["java", "-Xms250m", "-Xmx800m", "-XX:+UseG1GC", "-Djava.security.egd=file:/dev/./urandom", "-jar", …