【发布时间】:2019-04-22 13:56:58
【问题描述】:
我们有一些容器使用 docker 运行 java 进程。我们注意到的一件事是仅通过运行一个简单的 spring-boot 应用程序就占用了大量内存,甚至不包含我们自己的代码(只是为了尝试获得某种内存配置文件,而与我们可能引入的任何问题无关)。
我看到的是 docker/JVM 消耗的内存在 2.5 左右徘徊。我们确实在其中包含了相当数量的额外的 deps(camel、hibernate、一些 spring-boot 的 deps),但这并不是真正让我失望的东西。我看到的是,尽管 docker 说它为应用程序消耗了 2.5GB 的内存,但运行 jconsole 读取它消耗的内存高达 1GB(在 GC 后下降到 ~200MB 并缓慢攀升)。 docker 上的内存占用也保持在 GC 之后的位置(2.5GB)。
此外,当我转储堆以查看哪些类型的对象占用了该空间时,在我将 .hprof 文件加载到 MAT 后,堆看起来只有 33MB 大。这些对我来说都没有多大意义。目前,我正在查看 jconsole 中报告的非堆空间为 115MB,而堆空间为 331MB。
我已经阅读了大量(在 SO 和其他网站上)关于 JVM 内存区域的内容,以及一些专门报告堆转储可能更小的内容,但它们都没有我能说的那么远,而且除此之外,许多需要注意的建议是,每当进行堆转储时都会运行 GC,并且 MAT 具有显示或隐藏无法访问的对象的设置。所有这些都是在发帖之前考虑到的,现在我只是觉得有别的东西在起作用,我无法捕捉到自己,也没有在网上找到。
我完全预计这些数字可能会有些偏差,但在查看 docker 报告的内存使用情况时,它们在最佳情况下会下降 10 倍,而在查看 docker 报告的内存使用情况时会下降近 100 倍,这似乎是极端的.
有人知道我在这里可能缺少什么吗?
编辑:这也是一个运行 Java 8 的应用程序,尚未运行 Java 11。它在 JIRA 板上做,但尚未计划。
EDIT2:添加屏幕截图。 JConsole 屏幕截图中的峰值来自运行 GC。
【问题讨论】:
-
如果您可以发布一些实际输出(例如 jconsole 屏幕截图)可能会有所帮助
-
完成。感谢您的建议。
-
and off by nearly a factor of 100 when looking at the docker-reported memory usage.- 可能是 docker 报告了图像占用的整个内存,而不仅仅是你的 java 应用程序? -
我以为是,但实际上从 docker 容器内的进程中读取内存显示,是的,它几乎完全是 java 应用程序。作为参考,这是一个相当轻量级的高山 docker 容器。
标签: java linux spring-boot