Reputation: 6227
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... :)
Upvotes: 12
Views: 3651
Reputation: 38444
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:
Also see https://github.com/TimeAndSpaceIO/SmoothieMap.
Upvotes: 11
Reputation: 27727
You can avoid a lot of the Garbage Collection if you store your map entries off-heap. There are a number of libraries that can help you with that:
Upvotes: 4
Reputation: 1853
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.
Upvotes: 7
Reputation: 371
The LibGdx libraries have ArrayMap, which is a no-garbage version of hashmap.
http://libgdx.badlogicgames.com/
They have several other no-garbage collections. https://github.com/libgdx/libgdx/tree/master/gdx/src/com/badlogic/gdx/utils
They work great, with a minor limitation of not allowing nested recursion for the same iterator.
Upvotes: 2