Infinispan 9,复制缓存即将过期,但不允许将它们从 JVM 堆中删除

Infinispan 9, Replicated Cache is Expiring Entries but never allows them to be removed from JVM heap

正在对 infinispan/jgroups 之上的集群解决方案进行一些内部测试,并注意到由于对 expiration-reaper 的引用,过期的条目永远不会符合 GC 的条件,同时有超过 1集群中启用过期/禁用驱逐的节点。 由于一些系统问题,正在使用以下版本:

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

所以问题是:

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

示例:

缓存管理器:

return new DefaultCacheManager("infinispan.xml");

infinispan.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());

一些信息/试用:

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

  • 始终为将要通过 replicated/synchronized 缓存传输的自定义对象实施可序列化/hashCode/equals
  • 永远不要放置原始数组,因为 hashcode / equals 不会被有效计算 -
  • 不要在复制缓存上使用删除策略启用逐出,因为达到最大限制后,条目将被随机删除 - 基于 TinyLFU - 而不是基于过期计时器并且永远不会从JVM 堆。