不久前,我问了这个关于 ChronicleMap 被用作Map<String,Set<Integer>>
. 基本上,我们有一个集合,其平均值Set<Integer>
可能为 400,但最大长度为 20,000。在 ChronicleMap 2 中,这导致了相当严重的 JVM 崩溃。我搬到了 ChronicleMap 3.9.1 并且现在已经开始出现异常(至少它不是 JVM 崩溃):
java.lang.IllegalArgumentException: Entry is too large: requires 23045 chucks, 6328 is maximum.
at net.openhft.chronicle.map.impl.CompiledMapQueryContext.allocReturnCode(CompiledMapQueryContext.java:1760)
at net.openhft.chronicle.map.impl.CompiledMapQueryContext.allocReturnCodeGuarded(CompiledMapQueryContext.java:120)
at net.openhft.chronicle.map.impl.CompiledMapQueryContext.alloc(CompiledMapQueryContext.java:3006)
at net.openhft.chronicle.map.impl.CompiledMapQueryContext.initEntryAndKey(CompiledMapQueryContext.java:3436)
at net.openhft.chronicle.map.impl.CompiledMapQueryContext.putEntry(CompiledMapQueryContext.java:3891)
at net.openhft.chronicle.map.impl.CompiledMapQueryContext.doInsert(CompiledMapQueryContext.java:4080)
at net.openhft.chronicle.map.MapEntryOperations.insert(MapEntryOperations.java:156)
at net.openhft.chronicle.map.impl.CompiledMapQueryContext.insert(CompiledMapQueryContext.java:4051)
at net.openhft.chronicle.map.MapMethods.put(MapMethods.java:88)
at net.openhft.chronicle.map.VanillaChronicleMap.put(VanillaChronicleMap.java:552)
我怀疑这仍然是因为我的值与平均值相差甚远。我假设 ChronicleMap 根据我给构建器的平均值确定最大块数为 6328,但没想到会有一个需要 23045 个块的巨大值。
所以我的问题是:解决这个问题的最佳方法是什么?我正在考虑的一些方法,但仍然不确定:
- 使用
ChronicleMapBuilder.maxChunksPerEntry
或ChronicleMapBuilder.actualChunkSize
。也就是说,我如何确定性地确定应该设置什么?此外,如果设置得太高,这可能会导致大量碎片和性能下降,对吧? - 有一个“最大集合大小”并将非常大的集合分成许多较小的集合,相应地设置密钥。例如,如果我的密钥
XYZ
产生Set<Integer>
大小为 10000 的密钥,也许我可以将其拆分为 5 个密钥XYZ:1
、XYZ:2
等,每个密钥的大小为 2000。这感觉就像我可以在 ChronicleMap 中配置的东西一样,并且导致很多代码感觉它不应该是必要的。我在另一个问题中也提到了同样的计划。
其他想法/想法表示赞赏!