简体   繁体   English

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

[英]Which data structure uses more memory?

Which type of data structure uses more memory? 哪种类型的数据结构使用更多的内存?

  • Hashtable 哈希表
  • Hashmap 哈希图
  • ArrayList 数组列表

Could you please give me a brief explanation which one is less prone to memory leakage? 您能否给我一个简短的解释,哪一个更不容易发生内存泄漏?

...which one to use for avoiding the memory leakage ...用于避免内存泄漏的哪一个

The answer is all of them and none of them. 答案是所有人没有人。

Memory leakage is not related to the data structure, but the way you use them. 内存泄漏与数据结构无关,而与使用它们的方式有关。

The amount of memory used by each one is irrelevant when you aim to avoid "memory leakage". 为了避免“内存泄漏”,每个用户使用的内存量都是无关紧要的。

The best thing you can do is: When you detect an object won't be used any longer in the application, you must remove it from the collection ( not only those you've listed, but any other you might use; List, Map, Set or even arrays ). 您可以做的最好的事情是:当您检测到某个对象将不再在应用程序中使用时,您必须将其从集合中删除(不仅是列出的对象,而且还可能使用的其他对象;列表,地图,设置甚至是数组)。

That way the garbage collector will be able to release the memory used by that object. 这样,垃圾收集器将能够释放该对象使用的内存。

You can take a look at this article "How does garbage collector works" for further explanation on how Java release memory from the objects it uses. 您可以查看本文“垃圾收集器的工作原理”,以进一步说明Java如何从其使用的对象释放内存。

Edit: 编辑:

There are others data structures in Java which help for the references management such as WeakHashMap , but this may be considered as "advanced topics". Java中还有其他有助于引用管理的数据结构,例如WeakHashMap ,但可以将其视为“高级主题”。

Most likely you should really just use a Collection that suits your current need. 您很可能真的应该只使用适合您当前需求的Collection。 In the most common cases, if you need a List , use ArrayList , and if you need a Map , use HashMap . 在最常见的情况下,如果需要List ,请使用ArrayList ,如果需要Map ,请使用HashMap For a tutorial, see eg http://java.sun.com/docs/books/tutorial/collections/ 有关教程,请参见例如http://java.sun.com/docs/books/tutorial/collections/

When your profiler shows you there is an actual memory leak related to the use of Java Collections, then do something about it. 当你的探查表明你有涉及到使用Java集合的实际内存泄漏, 然后做一些事情。

Your question is woefully underspecified because the concrete data structures you specify are not of comparable structure. 由于您指定的具体数据结构不是可比较的结构,因此您的问题被严重指定不足。

The HashMap/HashTable are comparable since they both function as maps (key -> value lookups). HashMap / HashTable具有可比性,因为它们都充当映射(键->值查找)。 ArrayLists (and lists in general) do not. ArrayLists(通常是列表)没有。

The HashMap/HashTable part is easy to answer as they are largely identical (the major difference is null keys) but the former is not synchronized and the latter is, thus HashMap will generally be faster (assuming the synchronization is not required) Modern JVM's are reasonably fast at uncontended locks though so the difference will be small in a micro benchmark. HashMap / HashTable部分很容易回答,因为它们在很大程度上是相同的(主要区别是空键),但是前者是不同步的,而后者是同步的,因此HashMap通常会更快(假设不需要同步),现代JVM是不过,在无竞争的锁中,它的速度相当快,因此在微基准测试中差异很小。

Well, I've actually been, recently, in a situation where I had to hold onto large collections of custom objects, where the size of the collections was one of the applications limiting factors. 好吧,最近,我实际上不得不保持大量自定义对象的集合,其中集合的大小是应用程序限制因素之一。 If that's your situation, a few suggestions - 如果是您的情况,请提出一些建议-

  • there are a few implementations of collections using primitives (list here ). 有一些使用原语的集合的实现( 在此处列出)。 Played around a bit with trove4j, and found a somewhat smaller memory footprint (as long as you're dealing with primitives, of course). 与trove4j一起玩了一下,发现内存占用空间较小(当然,只要您处理的是原语)。
  • If you're dealing with large collections, you'll probably get more bang for your buck, in terms of reducing memory footprint, by optimizing the objects you're holding. 如果您处理的是大型馆藏,则可以通过优化所持有的对象来减少内存占用,从而获得更多收益。 After all, you've got a lot more of them, otherwise you wouldn't need a collection, right? 毕竟,您有更多的这些,否则您将不需要收藏,对吗?
  • Some collections are naturally smaller (eg LinkedList will be a bit smaller than an ArrayList) but the difference will probably be swamped by the differences in how they're used) 有些集合自然较小(例如,LinkedList会比ArrayList小一些),但差异可能会因使用方式的差异而被淹没。
  • Most of the java collections can be manually sized - you can set your arraylist of 100 elements to be initialized to 100 elements, and you can set your maps to keep less open space at the cost of slower performance. 大多数Java集合可以手动调整大小-您可以将要初始化的100个元素的arraylist设置为100个元素,还可以将地图设置为保留较少的开放空间,但会降低性能。 All in the javadocs. 全部在javadocs中。

Ultimately the simplest thing to do is to test for yourself. 最终,最简单的方法是对自己进行测试。

You're not comparing like with like: HashMap and Hashtable implement the Map interface, and ArrayList implements the List interface. 您没有在进行类似的比较: HashMapHashtable实现Map接口,而ArrayList实现List接口。

In a direct comparison between Hashtable and HashMap , HashMap will probably offer better performance because Hashtable is synchronized. HashtableHashMap之间进行直接比较时,由于Hashtable是同步的,因此HashMap可能会提供更好的性能。

If you give some indication about what you're using the collections for, you might get a more insightful answer. 如果您给出有关这些集合用途的一些指示,则可能会得到更深刻的答案。

Hashtables (be it HashMap or HashTable) would take a little more memory than what they use to actually store the information. 哈希表(无论是HashMap还是HashTable)将比它们实际用于存储信息的内存多一点。

Hashing performance comes at a price. 散列性能是有代价的。

A java.util.Collection stores references to objects. 一个java.util.Collection存储对对象的引用。

A java.util.Map stores references to Map.Entry instances, which hold references to keys and objects. java.util.Map存储对Map.Entry实例的引用,该实例保存对键和对象的引用。

So a java.util.Collection holding N references to objects will require less memory than a java.util.Map holding onto the same N references, because the Map has to point to the keys as well. 因此,与持有相同N个引用的java.util.Map相比,持有对对象的N个引用的java.util.Collection需要的内存更少,因为Map也必须指向键。

Performance for reading and writing differs depending on the implementation of each of these interfaces. 读写性能取决于这些接口中每个接口的实现。

I don't see any java.util.Collection analogous to WeakHashMap. 我看不到任何类似于WeakHashMap的java.util.Collection。 I'd read about that class if you're worried about garbage collection and memory leaks. 如果您担心垃圾回收和内存泄漏,那么我会阅读该类的内容。

As others have pointed out, your question is underspecified. 正如其他人指出的那样,您的问题没有得到充分说明。

Still, sometimes an ArrayList based implementation can replace a HashMap based implementation (I would not consider Hashtable at all, it's obsolete). 不过,有时基于ArrayList的实现可以替换基于HashMap的实现(我根本不会考虑Hashtable,它已经过时了)。 You might need to search the ArrayList linearly but for small Lists that might still be fast enough and the ArrayList will need less memory (for the same data), because it has less overhead. 您可能需要线性搜索ArrayList,但是对于可能仍然足够快的小列表,由于其开销较小,因此ArrayList需要较少的内存(对于相同的数据)。

In most languages it depends on how good you are at picking up your toys after you're done with them. 在大多数语言中,这取决于您完成玩具后拿起玩具的能力。

In Java, it doesn't matter since garbage collection is done automatically and you don't really need to worry about memory leaks. 在Java中,这无关紧要,因为垃圾收集是自动完成的,并且您实际上不必担心内存泄漏。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM