当前位置: 首页 > 知识库问答 >
问题:

Java堆大小随着Infinispan缓存变得太大

杨鸿畅
2023-03-14

我使用Infinispan缓存来存储值。代码每10分钟写入一次缓存,缓存大小约为400mb。它的生存时间约为2小时,最大条目数为1600万条,尽管目前在我的测试中,条目数没有超过200万条左右(我可以通过检查jconsole中的MBean/指标来了解这一点)。

当我启动jboss时,java堆大小是1.5Gb到2Gb。为jboss分配的最大内存的-Xmx设置是4Gb。

当我禁用Infinispan缓存时,堆内存使用量保持在1.5Gb到2Gb左右。它非常恒定并保持在该水平。

=

然而,随着时间的推移,它会继续增长和增长。每隔2到3个小时,垃圾回收机制就会完成一次,这将使用量降低到大约1或1.5Gb,但在30分钟内又会增加到3.5Gb。条目数量保持稳定在大约200万,因此这不是因为更多的条目进入缓存。(驱逐数量也保持在0)。

如果缓存只有400-500mb,什么可以保留这么多内存?是我的垃圾回收机制设置有问题吗?或者我应该查看Infinispan设置?

谢谢

编辑:事实证明这与Infinispan无关。我将问题缩小到一行占用大量内存的代码(比没有调用时多1Gb左右)。但我确实认为Infinispan缓存占用了越来越多的内存,这自然是因为在2小时的生存时间内添加了更多的条目。

我还需要有超过50个用户在Infinispan上查询。当堆达到这样的高值时(即使没有上面提到的内存泄漏),我知道这在java中不是一个错误场景,但是我需要尽可能多的可用内存。有没有办法“鼓励”堆转储超过某个点?我曾尝试使用GC选项为旧gen收集给定比例的堆,但通常堆的使用率会逐渐增加。

共有1个答案

姬英武
2023-03-14

您可能看到的是JVM没有收集已从缓存中驱逐的对象。缓存通常与流行的世代GC概念有着奇怪的关系。

世代GC的想法是,从广义上讲,JVM中有两种类型的对象——短期对象,它们被快速使用并丢弃,以及长期对象,它们通常在应用程序的整个生命周期中使用。在此模型中,您希望调整您的GC,以便您将大部分精力用于识别短期对象。这意味着您尽可能避免查看长期对象。

缓存通过具有一些中等长度的对象寿命(即几秒/分钟/小时,取决于缓存)来破坏此模式。这些对象通常会升级到终身生成,在需要完整的GC之前,通常不会查看它们,即使在从缓存中逐出之后也是如此。

如果发生了这种情况,那么您有两个选择:

  • 忽略它,让完整的GC语义学做它的事情,只要意识到这就是正在发生的事情。
  • 尝试调整GC,以便将对象提升到终身代需要更长的时间。有一些GC标志可以帮助解决这个问题。
 类似资料:
  • 问题内容: 所以我有一个使用Java堆的程序 我已将初始Java堆大小设置为5gb,将最大堆大小设置为12gb 但是当我查看任务管理器或资源监视器时,我的程序仅使用400mb。 所以这是我的问题: 初始Java堆大小是什么意思? 如果我将初始Java堆大小设置为5gb,为什么只看到程序上的RAM使用为400mb,而不是5gb呢?因为初始堆意味着最小大小,对吗? 问题答案: 在最大堆大小是堆可以长到

  • 上面链接中的代码正在工作,但可以传输到一定数量的数据。当我试图传输一个大小约为334 MB的.mkv格式的电影时,它给出了“内存不足,java堆大小”的错误。我是一个乞丐,我不知道如何解决这个问题,我试图在客户端程序中增加缓冲区大小,但问题仍然存在。请帮帮我.

  • 我对JavaFX有问题。当我调整窗口大小时,它会自动调整锚具的大小以适应。此外,帆布的宽度和高度属性也被绑定到锚烷上。因此,如果通过重新调整窗口本身,锚烷变大,画布也会变大。 但是当我把窗户变小,宽度和高度保持不变时,问题就来了。我真的不明白那里的行为。 因此,如果在使窗户更大的宽度和高度是100。然后在把窗口缩小后,它仍然是100。。。除息的 这是我的画布控制器。 以及我对应的FXML:

  • 我想检查我的应用程序是否很好地获得选项。 java进程在docker容器中运行。 为了做到这一点,我要找到所创建进程的最大堆大小。 null 假设(ngcmx+ogcmx)=()可以吗? https://docs.oracle.com/javase/8/docs/technotes/tools/unix/jstat.html

  • 我有两个应用程序使用相同的数据库实体。这两个应用程序都部署在jboss eap 6.2独立的集群上。DB表仅从一个应用程序中更新,但从两个应用程序中读取。这两个应用程序都使用本机hibernate API从数据库读取/写入数据。 在嵌入式模式下将infinispan启用为2LC后,如何确保在一个应用程序中更新的缓存实体从第二个应用程序缓存中失效?是否有任何JMX/JMS接口用于信号缓存失效? 若我

  • 在使用Java的生产中,我经常遇到一些完全的GC问题,我怀疑内存是由网络库分配来缓冲TCP请求结果的。 我已经在内存使用率很高(大约8GB)时转储了Java堆。我尝试用eclipse MAT分析。hprof文件,该文件大约有8GB。 由于eclipse MAT没有显示完整的堆转储内容,我不知道如何找到应用程序占用这么多内存的原因。