0

到目前为止,我们已经成功地使用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(我们稍后会升级;只是不想再摇摆不定)。

4

1 回答 1

1

如果不重现该错误,我无法 100% 确定,但我知道为什么会在这种情况下发生 JVM 崩溃。如果我是对的,如果您的条目大小超过 ChronicleMap 的 64 * chunkSize,就会发生这种情况。块大小可以直接配置,但如果你只配置平均键和值大小,它默认为2的幂,即在averageEntrySize/8和averageEntrySize/4之间,其中平均条目大小是你的averageKeySize和averageValueSize的总和,加上一些内部开销。因此,在您的情况下,如果您有平均值 - 400 或 500 个整数(每个 4 个字节)的集合,+ 小键,我想 chunkSize 计算为 256 个字节,所以您的条目应该小于 256 * 64 = 16384 字节。

同样,如果我的假设是正确的,那么 Chronicle Map 3 不应该有这个错误,并且应该允许任意大于平均大小或块大小的条目。

于 2016-05-27T12:29:48.627 回答