Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a HashMap implementation in Java that produces no garbage?

It came to my attention that java.util.HashMap produces garbage for the GC when used on my high-performance system, which basically is a selector reading from the network. Is there an alternative to java.util.HashMap (i.e. does not even need to implement java.util.Map, in other words, it can have its own API) that I can use that will leave no garbage behind?


GARBAGE = objects that go out of scope and will have to be collected by the GC.


For @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();
        }
    }
}

Now run that with -verbose:gc and see what happens... :)

like image 773
chrisapotek Avatar asked May 23 '14 11:05

chrisapotek


People also ask

Is HashMap garbage collected?

HashMap class is a Hashing based implementation. In HashMap, we have a key and a value pair. Even though the object is specified as key in hashmap, it does not have any reference and it is not eligible for garbage collection if it is associated with HashMap i.e. HashMap dominates over Garbage Collector.

Which Map is more efficient in Java?

TreeMap in Java The TreeMap class implements the Map interface by using a tree. A TreeMap provides an efficient means of storing key/value pairs in sorted order and allows rapid retrieval.

How efficient is Java HashMap?

HashMap, being a hashtable-based implementation, internally uses an array-based data structure to organize its elements according to the hash function. HashMap provides expected constant-time performance O(1) for most operations like add(), remove() and contains(). Therefore, it's significantly faster than a TreeMap.

How is a Java HashMap actually implemented?

Hashmap uses the array of Nodes(named as table), where Node has fields like the key, value (and much more). Here the Node is represented by class HashMapEntry. Basically, HashMap has an array where the key-value data is stored. It calculates the index in the array where the Node can be placed and it is placed there.


2 Answers

Yes. Take a look e.g. at Goldman Sachs collections.

They have a complete reimplementation of the JDK's collection framework (and much more) with an emphasis on low memory footprint. For example, their HashMap doesn't create the Entry objects until they really need to. Look at the documentation here.

There's also Javolution, a smaller library with a slightly different purpose - mainly for close-to-realtime and time-predictable classes, this also implies low garbage.

If you want to store primitives (which avoids the creation of their wrappers), look at one of these:

  • Trove - the "standard" collections for primitives
  • Goldman Sachs collections, again
  • HPPC - lower level access, often slightly faster than Trove, but enables you to shoot yourself into the foot more easily
  • Koloboke - a Trove fork made by people from OpenHFT. Insanely fast, evolving fast. As of now (September 2014), only Maps and Sets are supported.

EDIT 2020:

Also see https://github.com/TimeAndSpaceIO/SmoothieMap.

like image 182
Petr Janeček Avatar answered Oct 04 '22 02:10

Petr Janeček


We have also written a collection of data structures called CoralBits that provides high-performance with zero garbage creation. It re-uses iterators and pools map entry objects. For maps that use primitives as keys, we wrote IntMap and LongMap. For a general purpose map we wrote PooledHashMap which implements java.util.Map so you can swap in your code for zero garbage.

Trove and Javolution are other alternatives but we have found that Javolution creates garbage in some situations.

CoralBits also provides a MemorySampler instrumentation class that you can use to find out where garbage is being created in your code. In the case of a java.util.HashMap the culprit is:

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

You can take a look in this article written by me that gives an example of how to use MemorySampler to detect garbage in your applications.

Disclaimer: I am one of the developers of CoralBits.

like image 28
rdalmeida Avatar answered Oct 04 '22 04:10

rdalmeida