到目前为止,我们已经成功地使用ChronicleMap
了我们想要使用它的大多数东西,并且大多数数据集都工作得很好。我们的一个用例是将它用作多图,涵盖了这样做的大部分问题。Map<String,Set<Integer>>
在这种情况下,我们专门使用它。但是,我们遇到了一些有趣的 JVM 崩溃,并且难以找到确定性模式,因此我们可以避免它们。
因此,在我们将所有内容Set<Integer>
放入之前ChronicleMap
,我们将其完全放在 JVM 中,因此我们立即编写以减少碎片。由于我们将它完全保存在内存中,我们可以确定最大和平均Set<Integer>
大小是多少,并且可以轻松ChronicleMap
地使用ChronicleMapBuilder.averageValueSize
. 在大多数情况下,这工作得很好。
然而,在某些情况下,当 JVM 的大小Set<Integer>
偏离平均值时,JVM 会崩溃。例如,平均大小可能是 400,但我们可以有包含 20,000 个整数的异常值集。我们仍然可以使用一组 400 个整数的平均序列化大小来调整地图的大小,并且它开始填充ChronicleMap
得很好,直到它达到一个非常大的列表。
所以问题是:我如何计算出我可以偏离平均值有多大?我希望平均值确实是一个平均值,但似乎有一些最大值高于该值会导致 JVM 死机。
我们设计了一种算法将大集合拆分成更小的集合(例如,如果密钥是 AAA,那么现在有密钥 AAA:1、AAA:2、... AAA:n)。拆分集的大小是平均大小的 10 倍。换句话说,如果平均大小是 500,但我们有一个 20,000 的集合,我们会将其分成四个 5,000 (500 * 10) 的元素集合。
这在大多数情况下都有效,但随后我们遇到了另一个奇怪的案例,即使这种拆分也不够。我将因子减小到平均大小的 5 倍,现在它又可以工作了……但我怎么知道它足够小?我认为知道源问题或如何确定导致它的确切原因是最好的方法,但唉,我不知道为什么ChronicleMap
在这里挣扎。
另外,FWIW,我使用的是旧版本 2.1.17。如果这是在较新版本中修复的错误,我想知道有关该错误的一些详细信息,以及我们是否可以通过自己的方式避免它(例如拆分集合)但仍继续使用 2.1.17(我们稍后会升级;只是不想再摇摆不定)。