【问题标题】:Is there a HashMap implementation in Java that produces no garbage?Java中是否有不产生垃圾的HashMap实现?
【发布时间】:2014-07-12 18:22:55
【问题描述】:

我注意到java.util.HashMap 在我的高性能系统上使用时会为 GC 产生垃圾,这基本上是从网络读取的选择器。有没有可以替代java.util.HashMap 的替代方案(即甚至不需要实现java.util.Map,换句话说,它可以有自己的API)我可以使用它不会留下任何垃圾?


GARBAGE = 超出范围且必须由 GC 收集的对象。


对于@durron597:

public static void main(String[] args) {

    Map<String, String> map = new HashMap<String, String>();

    while(true) {

        map.put("foo1", "bah1");
        map.put("foo2", "bah2");

        map.remove("foo1");

        Iterator<String> iter = map.keySet().iterator();

        while(iter.hasNext()) {
            iter.next();
        }
    }
}

现在用 -verbose:gc 运行它,看看会发生什么... :)

【问题讨论】:

标签: java collections hashmap hashtable real-time


【解决方案1】:

是的。看看例如在Goldman Sachs collections

他们完全重新实现了 JDK 的集合框架(以及更多),强调低内存占用。例如,他们的HashMap 在真正需要之前不会创建Entry 对象。 Look at the documentation here.

还有 Javolution,一个较小的库,用途略有不同 - 主要用于接近实时和时间可预测的类,这也意味着低垃圾。

如果您想存储原语(避免创建它们的包装器),请查看以下内容之一:

  • Trove - 原语的“标准”集合
  • Goldman Sachs 再次收藏
  • HPPC - 较低级别的访问权限,通常比 Trove 稍快,但可以让您更轻松地射到自己的脚上
  • Koloboke - 由 OpenHFT 人员制作的 Trove 叉子。飞速发展,飞速发展。截至目前(2014 年 9 月),仅支持地图和集合。

2020 年编辑:

另见https://github.com/TimeAndSpaceIO/SmoothieMap

【讨论】:

【解决方案2】:

我们还编写了一个名为CoralBits 的数据结构集合,它提供了零垃圾创建的高性能。它重用迭代器和池映射条目对象。对于使用原语作为键的映射,我们写了IntMapLongMap。对于通用映射,我们编写了PooledHashMap,它实现了java.util.Map,因此您可以将代码换成零垃圾。

TroveJavolution 是其他替代方案,但我们发现 Javolution 在某些情况下会产生垃圾。

CoralBits 还提供了一个 MemorySampler 检测类,您可以使用它来找出在您的代码中创建垃圾的位置。对于java.util.HashMap,罪魁祸首是:

java.util.HashMap.createEntry(HashMap.java:901)

您可以查看我写的this article,它提供了一个如何使用 MemorySampler 检测应用程序中的垃圾的示例。

免责声明:我是 CoralBits 的开发者之一。

【讨论】:

  • 你怎么知道垃圾是在哪一行创建的?
  • 该行是分配对象的位置。至于会不会变成垃圾,那就另当别论了。在java.util.HashMap 的情况下,它是为 GC 释放的,所以它确实变成了垃圾。我们使用-javaagent 来执行此检测。
【解决方案3】:

如果您将地图条目存储在堆外,您可以避免大量垃圾收集。有许多库可以帮助您:

【讨论】:

  • 这可能是真的,但这取决于读写访问模式和堆外集合的 API。在读取路径上,如果每次读取数据时它们会反序列化堆外数据并为其创建新的 Java 对象表示,则某些堆外集合会产生比堆上集合更多的对象流失和垃圾。堆上集合可以通过每次返回已经在堆上的相同对象来避免这种情况。
【解决方案4】:

LibGdx 库有 ArrayMap,它是 hashmap 的无垃圾版本。

http://libgdx.badlogicgames.com/

他们还有其他几个无垃圾收集。 https://github.com/libgdx/libgdx/tree/master/gdx/src/com/badlogic/gdx/utils

它们工作得很好,有一个小的限制是不允许对同一个迭代器进行嵌套递归。

【讨论】:

    猜你喜欢
    • 2015-05-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-22
    • 1970-01-01
    • 2011-01-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多