JVM - XMX限制 VS 进程所消耗的内存

18 浏览
0 Comments

JVM - XMX限制 VS 进程所消耗的内存

我有关于Java应用程序使用的常驻内存的2个问题。

一些背景细节:

  • 我已经设置了-Xms2560M -Xmx2560M的Java应用程序。
  • Java应用程序正在容器中运行。 k8s允许容器最多使用4GB。

问题:

有时,流程会由k8s重新启动,出现错误137,显然进程已达到4GB。

应用程序行为:

  • 堆:应用程序似乎以所有内存使用,然后释放,然后再次使用等方式工作。

此快照说明了它。 Y列是空闲堆内存。 (由应用程序提取的((double)Runtime.getRuntime().freeMemory()/Runtime.getRuntime().totalMemory())*100

\"enter

我还能够使用HotSpotDiagnosticMXBean进行确认,该方法允许使用可达对象和包括不可达对象的转储创建一个转储。

不可达性大小为XMX。

另外,当在机器上创建一个转储时,驻留内存可以显示3GB,而转储的大小为0.5GB。(使用jcmd拍摄)

第一个问题:

这是合理的行为还是表示内存使用问题?

看起来不像典型的泄漏。

第二个问题

我看到了更多的问题,试图了解应用程序使用的驻留内存包括什么。

值得一提:

Java使用的内存比堆大小多得多(或将Docker内存限制正确地调整大小)

JVM消耗的本地内存与Java进程总内存使用量

不确定这些内容是否可以解释XMX和4GB k8s限制之间的1-1.5 GB。

如果您要提供某种检查列表来接近这个问题,它将是什么?(感觉看不到树林只看到树木)

有没有可以帮助的免费工具?(除了分析内存转储的工具)

admin 更改状态以发布 2023年5月21日
0
0 Comments

除了 tquadrat 发表的答案之外,您还需要考虑当应用程序使用原生内存映射的字节缓冲区时会发生什么情况,这些字节缓冲区在堆空间之外,但被进程占用。

0
0 Comments

你为堆分配了2.5GB的空间,JVM本身和操作系统的组件也会占用一些内存(一般规则是1GB,但如果在容器中运行时,实际数值可能会有相当大的差别),所以我们已经有了3.5GB的使用空间。

自从Java 8以后,JVM不再将类的代码存储在堆中,而是存储在一个称为“元空间”的区域中;根据程序的具体情况、使用的类数量和ClassLoader数量,此区域可能会很容易地增长超过0.5GB。这个需要加入考虑,除了那些链接文章中提到的因素。

0