当值大小

时间:2016-05-25 18:58:04

标签: java chronicle chronicle-map

到目前为止,我们已经使用ChronicleMap成功完成了我们想要使用它的大部分内容,并且大多数数据集都运行得很好。我们使用的一个用例是将其用作多图,涵盖了大部分问题。在这种情况下,我们特别将其用作Map<String,Set<Integer>>。但是,我们遇到了一些有趣的JVM崩溃,并且无法找到确定性模式,因此我们可以避免它们。

因此,在我们将所有Set<Integer>放入ChronicleMap之前,我们将它完全放在JVM中,因此我们立即编写以减少碎片。由于我们完全将其存储在内存中,因此我们可以确定最大和平均Set<Integer>大小的大小,并且可以使用ChronicleMap轻松调整ChronicleMapBuilder.averageValueSize的大小。在大多数情况下,这很好用。

但是,在某些情况下,当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 (我们稍后会升级;只是不想让船更加晃动)。

1 个答案:

答案 0 :(得分:1)

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

再次,如果我在我的小说中出现这个错误,那么,Chronicle Map 3不应该有这个错误,应该允许任意大于平均大小或块大小的条目。