【问题标题】:Which data structure uses more memory?哪种数据结构使用更多内存?
【发布时间】:2009-02-10 14:25:10
【问题描述】:

哪种类型的数据结构使用更多的内存?

  • 哈希表
  • 哈希图
  • 数组列表

能否请您简要解释一下哪个更不容易发生内存泄漏?

【问题讨论】:

  • 好的,我想我们现在要删除所有的 cmets?

标签: java data-structures memory-management


【解决方案1】:

...使用哪一个来避免内存泄漏

答案是全部,而没有

内存泄漏与数据结构无关,而与你使用它们的方式有关。

当您旨在避免“内存泄漏”时,每个人使用的内存量无关紧要。

您能做的最好的事情是:当您在应用程序中检测到一个将不再使用的对象时,您必须将其从集合中删除(而不是仅列出您列出的那些,但您可能使用的任何其他;List、Map、Set 甚至是数组)。

这样垃圾收集器将能够释放该对象使用的内存。

您可以查看这篇文章"How does garbage collector works",进一步了解 Java 如何从它使用的对象中释放内存。

编辑:

Java 中还有其他数据结构有助于引用管理,例如WeakHashMap,但这可能被视为“高级主题”。

【讨论】:

  • 您的答案中是否有可能引用 Wea​​kHashMap? :)
  • 考虑到这个问题,以及似乎对一些基本概念的误解,进入像 WeakHashMap 这样的“高级”内容可能会适得其反。好吧,也许快速提及一下就可以了。
  • @Mr Potato:也许现在就这样放着比较好。
  • @Mr.土豆和乔尼克:完成!反正我之前没有用过WHM。我没有这个需要。不过理论上我知道;)
  • 最近我看到了这个相关的演示文稿:domino.research.ibm.com/comm/research_people.nsf/pages/…
【解决方案2】:

您很可能应该只使用适合您当前需求的集合。在最常见的情况下,如果您需要List,请使用ArrayList,如果您需要Map,请使用HashMap。有关教程,请参见例如http://java.sun.com/docs/books/tutorial/collections/

当您的分析器显示存在与使用 Java 集合相关的实际内存泄漏时,然后对此采取一些措施。

【讨论】:

    【解决方案3】:

    可悲的是,您的问题未充分说明,因为您指定的具体数据结构不是具有可比性的结构。

    HashMap/HashTable 具有可比性,因为它们都用作映射(键 -> 值查找)。 ArrayLists(和一般的列表)没有。

    HashMap/HashTable 部分很容易回答,因为它们在很大程度上是相同的(主要区别是空键),但前者不同步,后者是,因此 HashMap 通常会更快(假设不需要同步)现代 JVM 在非竞争锁方面相当快,因此在微基准测试中差异会很小。

    【讨论】:

      【解决方案4】:

      嗯,实际上,我最近一直处于必须持有大量自定义对象的情况,其中集合的大小是应用程序的限制因素之一。如果这是您的情况,请提出一些建议 -

      • 有几个实现 使用原语的集合(列表 here)。玩了一下 trove4j,发现了一个更小的 内存占用(只要你 当然是处理原语)。
      • 如果您正在处理大型 收藏,你可能会得到更多 就您而言,物超所值 减少内存占用,通过 优化你的对象 保持。毕竟你有很多 更多,否则你不会 需要收藏,对吗?
      • 有些集合自然更小(例如,LinkedList 会比 ArrayList 小一点),但差异可能会被它们的使用方式的不同所淹没)
      • 大多数 java 集合都可以手动调整大小 - 您可以将包含 100 个元素的数组列表设置为初始化为 100 个元素,并且可以将地图设置为以降低性能为代价保留更少的开放空间。全部在 javadocs 中。

      最终,最简单的事情就是自己测试。

      【讨论】:

        【解决方案5】:

        您没有将同类与同类进行比较:HashMapHashtable 实现了 Map 接口,ArrayList 实现了 List 接口。

        HashtableHashMap 之间的直接比较中,HashMap 可能会提供更好的性能,因为Hashtable 是同步的。

        如果您说明您将这些集合用于什么目的,您可能会得到更有洞察力的答案。

        【讨论】:

          【解决方案6】:

          Hashtables(无论是 HashMap 还是 HashTable)会比它们用于实际存储信息的内存占用更多​​的内存。

          哈希性能是有代价的。

          【讨论】:

            【解决方案7】:

            java.util.Collection 存储对对象的引用。

            java.util.Map 存储对 Map.Entry 实例的引用,其中包含对键和对象的引用。

            因此,持有 N 个对象引用的 java.util.Collection 将比持有相同 N 个引用的 java.util.Map 需要更少的内存,因为 Map 也必须指向键。

            读写性能因这些接口的实现而异。

            我没有看到任何类似于 WeakHashMap 的 java.util.Collection。如果您担心垃圾收集和内存泄漏,我会阅读该课程。

            【讨论】:

              【解决方案8】:

              正如其他人所指出的,您的问题未详细说明。

              不过,有时基于 ArrayList 的实现可以替换基于 HashMap 的实现(我根本不会考虑 Hashtable,它已经过时了)。您可能需要线性搜索 ArrayList,但对于可能仍然足够快的小型列表,并且 ArrayList 将需要更少的内存(对于相同的数据),因为它的开销更少。

              【讨论】:

                【解决方案9】:

                在大多数语言中,这取决于你用完玩具后捡起玩具的能力。

                在 Java 中,这无关紧要,因为垃圾收集是自动完成的,您不必担心内存泄漏。

                【讨论】:

                • 这根本不是真的。在 Java 中仍然可能存在内存泄漏——垃圾收集器将收集没有引用的对象,但如果应用程序维护对未使用对象的引用,那当然可以归类为内存泄漏!
                • 土豆头先生是对的。在 Java 中,内存泄漏在处理集合时更容易受到影响,并且在不再需要时不删除项目。例如,如果堆栈是用 ArrayList 实现的,并且在弹出项目时没有放置空指针,则可能存在泄漏。
                猜你喜欢
                • 1970-01-01
                • 2017-10-27
                • 2014-08-12
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2012-02-16
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多