jvm 与% used相比,堆大小异常大

zujrkrfu  于 2022-11-23  发布在  其他
关注(0)|答案(4)|浏览(97)

我有一个内存分配问题,希望您能帮助解决。我们在top中分析了一些服务,我们注意到它们的RES值约为1.8GB,据我所知,这意味着它们当时拥有1.8GB的内存。如果我们刚启动它们,这将是很好的(它们实际上是从一个缓存中读取数据,进行处理,然后推送到另一个缓存),但是在CPU密集型处理完成后,我们仍然看到这种情况,我们想知道这是否意味着某些东西没有像我们预期的那样被GC。
我们使用以下参数运行程序:-Xms 256 m-Xmx 3096 m据我所知,这意味着初始堆大小为256,最大堆大小为3096。
现在,我 * 期望 * 看到的是堆最初根据需要增长,然后随着内存被释放而根据需要收缩(尽管这可能是我的第一个错误)。

  • 3分钟:已用堆为1GB,堆大小为2GB
  • 5分钟内:我们已经完成了处理,因此已使用的堆急剧下降到接近零,但堆大小仅下降到约1.5GB
  • 7分钟-〉:定期进行少量真实的处理,使用的堆仅在100- 200 MB左右,堆大小保持恒定,约为1.7GB。

我的问题是,为什么我的堆没有像我预期的那样缩小?这不是在掠夺linux机器上其他进程的宝贵内存吗?如果是这样,我该如何修复它?我们确实有时会看到内存不足的错误,而这些进程被分配了最“意外”的内存大小,我认为最好从它们开始。
干杯,戴夫。
(~请原谅可能对JVM内存调优缺乏了解!)

zaq34kh6

zaq34kh61#

你可能想看看这个关于调整堆的扩展和收缩的答案。默认情况下,JVM不会太积极地收缩堆。此外,如果堆在很长一段时间内有足够的空闲空间,它不会触发GC,我相信这是唯一考虑收缩堆的时候。
理想情况下,您可以将最大值配置为一个值,该值可以为您的应用程序在全负载下提供足够的余量,但如果它一直处于使用状态,操作系统性能也可以接受。将最小值设置为最大值以实现可预测性和潜在的更好性能并不罕见(我没有任何可供参考的临时值)。

wi3ka0sx

wi3ka0sx2#

我没有一个完整的答案,但类似的问题以前也出现过。从前面的讨论中,您应该研究一下-XX:MaxHeapFreeRatio=作为您的调优参数,以强制将堆释放回操作系统。还有documentation here,我相信默认值允许JVM保留大量未使用的堆。

qzlgjiam

qzlgjiam3#

好吧,GC并不总是在你想的时候运行,它也不总是收集合格的对象。它可能只在旧gen空间几乎用完堆空间的时候才开始收集对象(因为从旧gen空间收集通常会涉及到停止收集,GC试图避免这种收集,直到它真正需要这样做)。

q3aa0525

q3aa05254#

也许您可以尝试一些剖析,使用TPTP、visualvm或JProbe(商业,但试用版可用),以找出究竟发生了什么。
另一个需要注意的是文件处理程序;我不知道细节,但我的一个同事在几年前遇到了一个堆饱和问题,这个问题是由一个打开许多文件的进程引起的,他发现每次打开一个文件时,都会在本机堆中分配一个4kb的缓冲区,在处理结束时释放。我希望这个相当模糊的指示可能会有所帮助...

相关问题