OpenHFT ChronicleMap内存分配和限制

时间:2016-09-04 19:27:08

标签: java memory chronicle-map

这篇文章可能是OpenHFT常见问题的一个很好的候选人。

我正在玩ChronicleMap考虑它的想法,但有很多问题。我相信大多数正在研究这个产品的初级程序员都有类似的考虑。

您会解释如何在此API中管理内存吗?

ChronicleMap宣布了一些非常出色的TB堆外内存资源可用于处理其数据,我希望对此有清晰的认识。

让我们来看一个拥有500GB高清和4GB内存笔记本电脑的程序员。在这种情况下,纯数学sais - 'swapped'内存的总资源是504GB。让我们给操作系统和其他程序一半,我们留下250GB高清和2GB内存。你能详细说明ChronicleMap可以分配的数量相对于可用资源的实际可用内存吗?

下一个相关问题与ChronicleMap的实现有关。

我的理解是每个ChronicleMap分配它使用的内存块,并且当我们能够准确地预测通过的数据量时,实现最佳性能/内存使用。然而,这是一个充满活力的世界。

让我们设置一个(夸大但可能的)例子:

假设K(关键)'城市'的地图及其V(值) - '描述'(城市的),并允许用户对描述长度有很大的限制。

第一个用户输入:K = "Amsterdam"V = "City of bicycles",此条目用于声明地图 - 它为这对创造了先例:

ChronicleMap<Integer, PostalCodeRange> cityPostalCodes = ChronicleMap
    .of(CharSequence.class, CharSequence.class)
    .averageKey("Amsterdam")
    .averageValue("City of bicycles")
    .entries(5_000)
    .createOrRecoverPersistedTo(citiesAndDescriptions);

现在,下一个用户被带走并写了关于布拉格的分析 他转到:K = "Prague"V = "City of 100 towers is located in the hard of Europe ... blah, blah... million words ..."

现在程序员已经预计会有最多5_000个条目,但它已经失控了,而且有数千个条目。

ChronicleMap是否会为这种情况自动分配内存?如果是,是否有更好的方法为此动态解决方案声明ChronicleMaps?如果不是,你会推荐一种方法(最好的代码示例)如何最好地处理这种情况?

如何使用持久性来处理文件?

ChronicleMaps可以耗尽我的RAM和/或磁盘空间吗?避免这种情况的最佳做法是什么?

换句话说,请解释在估计值过低和价值(和/或密钥)长度和条目数量过高的情况下如何管理存储器。

其中哪些适用于ChronicleMap?

  1. 如果我分配大块(.entries(1_000_000).averageValueSize(1_000_000)且实际使用率为 - 条目= 100,平均值大小= 100。
  2. 会发生什么?:

    1.1。 - 一切正常,但会有大量的浪费 - 未使用?

    1.2。 - 一切正常,未使用的内存可用于:

    1.2.1 - ChronicleMap

    1.2.2 - 使用ChronicleMap的给定线程

    1.2.3 - 给定过程

    1.2.4 - 给定JVM

    1.2.5 - 操作系统

    1.3。 - 请解释未使用的内存是否还有其他问题

    1.4。 - 超大型声明对我的持久性文件做了什么?

    1. 与案例1相反 - 我分配小块(.entries(10).averageValueSize(10),实际使用量为1_000_000s个条目,平均值大小= 1_000s个字节。  会发生什么?:

1 个答案:

答案 0 :(得分:4)

  

让我们来看一个拥有500GB高清和4GB内存笔记本电脑的程序员。在这种情况下,纯数学sais - 'swapped'内存的总资源是504GB。让我们给操作系统和其他程序一半,我们留下250GB高清和2GB内存。你能详细说明ChronicleMap可以分配的数量相对于可用资源的实际可用内存吗?

在这样的条件下,Chronicle Map将非常缓慢,每次使用Chronicle Map的操作平均有2个随机磁盘读写(总共4个随机磁盘操作)。当数据库大小远大于内存时,传统的基于磁盘的数据库引擎(如RocksDBLevelDB)应该可以更好地工作。

  

现在程序员已经预计会有最多5_000个条目,但它已经失控了,而且有数千个条目。

     

ChronicleMap是否会为这种情况自动分配内存?如果是,是否有更好的方法为此动态解决方案声明ChronicleMaps?如果不是,你会推荐一种方法(最好的代码示例)如何最好地处理这种情况?

Chronicle Map将分配内存,直到插入的实际条目数除以通过ChronicleMappBuilder.entries()配置的数字不高于配置的ChronicleMapBuilder.maxBloatFactor()。 E. g。如果你创建一个地图

ChronicleMap<Integer, PostalCodeRange> cityPostalCodes = ChronicleMap
    .of(CharSequence.class, CharSequence.class)
    .averageKey("Amsterdam")
    .averageValue("City of bicycles")
    .entries(5_000)
    .maxBloatFactor(5.0)
    .createOrRecoverPersistedTo(citiesAndDescriptions);

当大小为~25 000时,它将开始抛出IllegalStateException尝试插入新条目。

但是,当实际大小远远超出配置的大小时,Chronicle Map的工作速度会逐渐变慢,因此最大可能maxBloatFactor()被人为限制为1000.

现在的解决方案是通过entries()(以及averageKey()averageValue())至少大致正确地配置纪事地图的未来尺寸。

提前配置合理的Chronicle Map的大小的要求被认为是可用性问题。 There is a way to fix this and it's on the project roadmap.

  

换句话说,请解释在估计值过低和价值(和/或密钥)长度和条目数量过高的情况下如何管理存储器。

键/值大小低估:空间在hash lookup area中被浪费,每个条目大约8字节*低估因子。因此,如果实际平均条目大小(键+值)很小,则可能非常糟糕。 G。 50个字节,你已经配置为20个字节,你将浪费~8 * 50/20 = 20个字节,或40%。平均入门尺寸越大,浪费越小。

键/值大小过高:如果只配置键和值平均大小,而不是直接actualChunkSize(),则实际的块大小会自动选择在1/8和1/4之间平均条目大小(键+值)。实际的块大小是Chronicle Map中的分配单元。因此,如果将平均条目大小配置为~1000字节,则实际的块大小将在125到250字节之间选择。如果实际平均条目大小只有100个字节,则会占用大量空间。如果估计过高,预期的空间损失将限制在数据大小的20%左右。

因此,如果您担心可能会高估平均键/值大小,请明确配置actualChunkSize()

低估的条目数:如上所述。没有特别的空间浪费,但是Chronicle Map的工作速度越慢,低估就越差。

条目数量高估:内存浪费在哈希查找区域,每个条目大约8字节*高估率。请参阅上面键/值大小低估部分,了解它的好坏程度,具体取决于实际的平均条目数据大小。