jvm-xmx限制与进程消耗的内存

pcrecxhr  于 2021-06-30  发布在  Java
关注(0)|答案(2)|浏览(384)

关于java应用程序使用的驻留内存,我有两个问题。
一些背景细节:
我用-xms2560m-xmx2560m设置了一个java应用程序。
java应用程序正在容器中运行。k8s允许容器消耗高达4gb的容量。
问题是:
有时进程被k8s重新启动,错误137,显然进程已经达到4gb。
应用行为:
heap:应用程序的工作方式似乎是先使用所有内存,然后释放内存,再使用内存等等。
这个快照说明了这一点。y列是可用堆内存(由应用程序提取 ((double)Runtime.getRuntime().freeMemory()/Runtime.getRuntime().totalMemory())*100 )

我还可以使用hotspotdiagnosticmxbean来确认它,它允许创建一个包含可访问对象和一个也包含不可访问对象的转储。
一个无法到达的是在xmx的大小。
此外,这也是我在机器上创建转储时看到的,驻留内存可以显示3gb,而转储的大小是0.5gb(与jcmd合拍)
第一个问题:
这是合理的行为还是表示内存使用问题?看起来不像是典型的泄漏。
第二个问题
我看到了更多的问题,试图理解应用程序使用的驻留内存是由什么组成的。
值得一提的是:
java使用的内存比堆大小(或docker内存限制)多得多

jvm消耗的本机内存与java进程总内存使用量之比
不确定这些是否可以解释xmx和4gbk8s限制之间的1-1.5gb。
如果你要提供一个检查表来解决这个问题,那会是什么(感觉我看不见森林了)
有什么免费的工具可以帮忙吗(除了那些用来分析内存转储的)

nzk0hqpo

nzk0hqpo1#

为堆分配2.5 gb,jvm本身和操作系统组件也会占用一些内存(这里的重击规则是1 gb,但实际数字可能会有很大差异,特别是在容器中运行时),因此我们已经是3.5 gb了。
自Java8以来,jvm将不再将类的代码存储在堆上,而是存储在称为“元空间”的区域中;根据您的程序正在执行的操作、它使用了多少类和多少类加载器,这个区域可能很容易扩展到0.5gb以上。这需要被考虑,除了那些在链接的帖子中提到的东西。

cgfeq70w

cgfeq70w2#

除了tquadrat给出的答案外,您还必须考虑当应用程序使用由字节缓冲区Map的本机内存时会发生什么情况,字节缓冲区位于堆空间之外,但被进程占用。

相关问题