【问题标题】:What is the most memory efficient method of storing a large number of Strings in a map?在地图中存储大量字符串的最节省内存的方法是什么?
【发布时间】:2016-06-15 14:00:56
【问题描述】:

我想在Map<String, MagicObject> 中存储大量字符串,以便可以快速访问MagicObjects。此 Map 的条目太多,以至于内存正在成为瓶颈。假设 MagicObjects 无法优化,那么在这种情况下我可以使用的最有效的地图类型是什么?我目前正在使用以下内容:

gnu.trove.map.hash.TCustomHashMap<byte[], MagicObject>

【问题讨论】:

  • 如果另一张地图突然使用更少的内存,我会感到惊讶,但我对优化应用程序的内存使用不太熟悉。
  • 你不会通过切换数据结构来改变JVM内存模型。
  • 为什么不用 THashMap ?
  • @duffymo 实际上你可以根据使用的类型节省内存:java-performance.info/memory-consumption-of-java-data-types-2(表在末尾)
  • 谢谢你,@dognose。我的说法仍然正确:您没有更改 JVM 内存模型。 “大量的字符串”仍然会占用他们将要占用的内容。但我不知道这个图书馆。 Trove 是开源的还是购买的库?你和它有关联吗? (完全公开和透明。)

标签: java string memory collections memory-optimization


【解决方案1】:

如果您的键足够长并且有很多足够长的公共前缀,那么您可以使用trie(前缀树)数据结构来节省内存。对 this question 的回答指向了 trie 的几个 Java 实现。

【讨论】:

    【解决方案2】:

    打开思路,考虑Huffman coding 先压缩你的字符串 放入地图,只要您的字符串是固定的(字符串的数量和内容不变)。

    【讨论】:

      【解决方案3】:

      我参加这个聚会有点晚了,但这个问题在相关搜索中出现并引起了我的兴趣。我通常不回答 Java 问题。

      此 Map 的条目太多,以至于内存正在成为瓶颈。

      我怀疑。

      要使内存中的字符串存储成为瓶颈,您需要大量的唯一字符串[1]。从长远来看,我最近使用了一个 180 万字的字典(180 万个独特的英文单词),它们在运行时占用了大约 1.6MB 的 RAM。

      如果您使用字典中的每个单词作为键,您仍将只使用 1.6MB 的 RAM[2] 来存储键,因此内存不会成为您的瓶颈。

      我怀疑您遇到的是字符串匹配的 O(n^2) 性能。我的意思是,随着更多键的添加,性能会成倍下降[3]。如果您使用字符串即键,这是不可避免的。

      如果您想加快速度,请将每个键存储到不存储重复项的哈希表中,并将哈希键用作映射的键​​。

      注意事项:

      [1] 我假设字符串都是唯一的,否则您不会尝试将它们用作映射的键​​。

      [2] 即使 Java 使用每个字符 2 个字节,它仍然只有 3.2MB 的内存,总计。

      [3] 如果您选择了错误的数据结构(例如不平衡二叉树)来存储您的值,它的运行速度会更慢。我不知道 map 是如何在内部存储值的,但是不平衡的二叉树会有 O(2^n) 的性能——几乎是你能找到的最差的性能。

      【讨论】:

      • 内存正在成为瓶颈,因为应用程序的内存消耗达到数百 GB,其中大部分与所述映射相关 - 我们确实在谈论数百万个条目,尽管很明显地图的值也占据了相当大的内存份额,不仅仅是字符串。关于您的建议,我确实尝试过,但后来发现使用自定义哈希算法的 Koloboke 地图实现提供了运行时性能和内存消耗的最佳组合。
      • 你的句子有问题我最近使用了一个 180 万字的字典(180 万个独特的英文单词),它们在运行时占用了大约 1.6MB 的 RAM。要么这些词没有同时加载到 RAM 中,要么它们被打包在具有某种压缩的数据结构中。在任何情况下,从具有 1.8m 项的集合中唯一引用任何元素都需要至少 3 个字节大小的句柄,因此如果所有这些词都用作映射中的键,则内存使用量的绝对最小值将为 5.4MB。跨度>
      猜你喜欢
      • 1970-01-01
      • 2012-04-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多