【发布时间】:2021-03-29 19:22:06
【问题描述】:
我有 2 个关于 Java 应用程序使用的常驻内存的问题。
一些背景细节:
- 我有一个使用 -Xms2560M -Xmx2560M 设置的 java 应用程序。
- Java 应用程序正在容器中运行。 k8s 允许容器最多消耗 4GB。
问题:
有时进程被k8s重启,报错137,显然进程已经达到4GB了。
应用行为:
- 堆:应用程序的工作方式似乎是使用所有内存,然后释放,然后使用等等。
这张快照说明了这一点。 Y 列是可用的堆内存。 (由((double)Runtime.getRuntime().freeMemory()/Runtime.getRuntime().totalMemory())*100应用程序提取
)
我还可以使用HotSpotDiagnosticMXBean 确认它,它允许创建一个包含可访问对象和一个还包含不可访问对象的转储。
无法访问的那个是 XMX 大小。
此外,这也是我在机器本身上创建转储时看到的,常驻内存可以显示 3GB,而转储的大小为 0.5GB。 (用jcmd拍摄)
第一个问题:
这是合理的行为还是表示内存使用问题? 这似乎不是典型的泄漏。
第二个问题
我看到了更多的问题,试图了解应用程序使用的常驻内存是由什么组成的。
值得一提:
Java using much more memory than heap size (or size correctly Docker memory limit)
和
Native memory consumed by JVM vs java process total memory usage
不确定这是否可以占 XMX 和 4GB k8s 限制之间的 1-1.5 GB。
如果您要提供某种检查清单来解决问题,那会是什么? (感觉好像只见树木不见森林)
任何可以提供帮助的免费工具? (除了那些用于分析内存转储的)
【问题讨论】:
-
在某些情况下,一个进程可能会消耗20GB内存,而堆只有2GB。这是否正常,完全取决于应用程序 - 我们不能在不知道您的特定应用程序的情况下说。例如。对于 Cassandra、Elasticsearch 或其他处理大量映射文件的 Java 进程来说,RSS 远远大于堆大小是很典型的。
-
你提到的帖子已经有了详细的答案。他们还列出了一系列用于分析本机内存问题的工具:Native Memory Tracking、pmap、jemalloc、async-profiler。查看相关的video,它描述了流行的本机内存问题并演示了如何解决这些问题。
标签: java memory memory-leaks garbage-collection jvm