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

在Infinispan 9中,复制缓存使条目过期,但从不允许将其从JVM堆中删除

颛孙和颂
2023-03-14

在infinispan/jgroups上对集群解决方案进行了一些内部测试,并注意到过期的条目永远不符合GC的条件,这是因为过期收割机上有一个引用,而集群中有多个节点启用了过期/禁用了逐出。由于一些系统问题,正在使用以下版本:

  • JDK 1.8
  • 英菲尼迪9.4.20
  • J组4.0.21

在我的示例中,我使用了一个简单的Java主场景,放置特定数量的数据,期望它们在特定时间段后过期。过期确实正在发生,因为它可以在访问过期条目时和相应的事件侦听器(如果已配置)时得到确认,因为它看起来永远不会从可用内存中删除,即使在显式GC之后或接近OOM错误时也是如此。

所以问题是:

这是否真的是预期的默认行为,或者我缺少群集复制/过期/序列化的关键配置

示例:

缓存管理器:

return new DefaultCacheManager("infinispan.xml");

英菲尼斯潘。xml:

  <jgroups>
     <stack-file name="udp" path="jgroups.xml" />
  </jgroups>

  <cache-container default-cache="default">
     <transport stack="udp" node-name="${nodeName}" />
     <replicated-cache name="myLeakyCache" mode="SYNC">
        <expiration interval="30000" lifespan="3000" max-idle="-1"/>
     </replicated-cache>
  </cache-container>

默认UDP jgroups xml,如打包示例所示:

.....

<UDP
        mcast_addr="${jgroups.udp.mcast_addr:x.x.x.x}"
        mcast_port="${jgroups.udp.mcast_port:46655}"
        bind_addr="${jgroups.bind.addr:y.y.y.y}"
        tos="8"
        ucast_recv_buf_size="200k"
        ucast_send_buf_size="200k"
        mcast_recv_buf_size="200k"
        mcast_send_buf_size="200k"
        max_bundle_size="64000"
        ip_ttl="${jgroups.udp.ip_ttl:2}"
        enable_diagnostics="false"
        bundler_type="old"
        thread_naming_pattern="pl"
        thread_pool.enabled="true"
        thread_pool.max_threads="30"
        />

虚拟缓存条目:

public class CacheMemoryLeak implements Serializable {
    private static final long serialVersionUID = 1L;
    Date date = new Date();
}

“服务”的示例用法:

Cache<String, Object> cache = cacheManager.getCache("myLeakyCache");
cache.put(key, new CacheMemoryLeak());

一些信息/选拔赛:

  • 当集群中只有一个节点或按顺序重新启动它们时,引用将被清除
  • 启用最大空闲显示相同的行为(有意义的是,到期收割机是相同的)
  • 启用逐出并不能解决问题,只是将“过期”引用计数保持在最大限制之间。如果很快达到这个目标,那么也会对活动条目进行随机逐出(默认删除策略)
  • 如果我将缓存项更改为本机字符串,则infinispan。与自定义对象相比,在下一个GC周期中,当到期并从expiration reaper标记时,将从堆空间中删除VerticacheEntries
  • 仅在一个节点中启用过期收割机无法解决此问题,可能会破坏故障切换机制
  • 升级至infinispan 10.1.8决赛,但面临同样的问题

共有1个答案

秦彦君
2023-03-14

似乎没有其他人有同样的问题,或者使用基本对象作为缓存项,因此没有注意到这个问题。在复制并幸运地找到了根本原因后,出现了以下几点:

  • 始终为将通过复制/同步缓存传输的自定义对象实现Serializable/hashCode/equals
  • 永远不要放置原始数组,因为hashcode/equals不会被计算-有效-
  • 不要在复制的缓存上使用删除策略启用驱逐,因为在达到最大限制时,条目会被随机删除-基于TinyLFU-而不是基于过期的计时器,并且永远不会从JVM堆中删除。
 类似资料:
  • 关于如何在Java代码中管理密码,有各种各样的问题和答案——例如,这里和这里。 讨论往往集中在使用< code>char[]而不是< code>String的优点上。 但是,如果是第三方库将密码存储在字符串中,有什么方法可以避免密码存储在JVM的堆中呢? 例如,在以下三种情况下,我认为密码将在JVM的生命周期内保留在堆中: 编辑-示例更新为与我的问题更相关: 在上面的示例中,我的对象在中包含密码。

  • 问题内容: 我有一个数组: 而且我还有一个不允许的单词数组: 我需要做的是删除第一个数组中也出现在第二个数组中的所有项目,例如,在这种情况下,键1将需要删除,因为“ and”在不允许的单词数组中。 现在,我现在有了这段代码,该代码对禁止的单词进行了foreach,然后使用array_search查找任何匹配项: 现在,我知道这段代码很烂,我想知道的是,是否存在一种更有效的方法来从另一个数组中存在的

  • 好吧,我有一个函数(不完全是下面写的那个,那个只是一个例子) 现在的问题是,人们可以进入控制台,只需键入“test()”并调用函数。 有没有办法防止这种情况?我不想让很多人从控制台调用函数。

  • 在我的mac崩溃后,每次同步我都会收到错误消息: 错误:无法从缓存taskartifacts.bin(/users/me/development/projectname/.gradle/2.10/taskartifacts/taskartifacts.bin)中读取条目“:RandomModuleName:CompilereleaseShaders”。 >[ljava.lanava.lang.;可

  • 我使用Minizip API来压缩和解压我的档案文件。我有一个要求,即在解压缩后立即从zip中删除zip条目。 如果zip归档文件有多个zip条目,我可以在解压缩后立即删除特定的zip条目,然后使用剩余的zip条目压缩归档文件。我可以用一个临时拉链来实现这一点。 但是当我在zip存档中有一个文件时,我只能在完全提取后删除zip。。。。对于这种情况,有没有一种优化方法,可以将zip条目分块提取和删除

  • 我有一个简单的JavaFX应用程序,它允许用户查询数据库并查看表中的数据。 我使用的是标准的javafx.Scene.Control.TableView类。是否有一种简单的方法来启用单元格复制?我做了一些搜索,我看到其他人创建自定义菜单命令...我不想创建一个自定义菜单,我只想要基本的键盘复制与单细胞工作。 我使用的是单一选择模式,但如果需要,我可以更改为其他模式: