如何解决JVM - XMX 限制与进程消耗的内存
我有两个关于 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。
如果您提供某种检查清单来解决问题,那会是什么? (感觉只见树木不见森林)
任何可以提供帮助的免费工具? (除了分析内存转储的那些)
解决方法
您为堆分配了 2.5 GB,JVM 本身和 OS 组件也会占用一些内存(这里的 thump 规则是 1 GB,但实际数字可能会有很大差异,尤其是在容器中运行时),所以我们已经达到 3.5 GB。
从 Java 8 开始,JVM 将不再将类的代码存储在堆中,而是存储在称为“元空间”的区域中;根据您的程序在做什么,它使用了多少个类和多少个类加载器,这个区域可能很容易增长到 0.5 GB 以上。除了链接帖子中提到的那些内容之外,还需要考虑这一点。
,除了 tquadrat 发布的答案之外,您还必须考虑当应用程序使用由字节缓冲区映射的本机内存时会发生什么,这些内存在堆空间之外但被进程占用。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。