minimizing garbage collection

hello,

my profiler told me that a major reason for the garbage collection is the boxing and unboxing of primitive types in hashmaps.

i use a lot of hashmaps like this

HashMap<Integer,MyObject>

and then query them like this

int key = 5;

hashmap.get(key);

the get function automatically creates a new Integer object, which is used onyl for the sake of calling the equals function in order to fetch the object of the map.

is there any way to avoid this creation of the Integer object? thanks!

Maybe try to use the WeakHashMap. your key wiil be weak-referenced so that it will avoid too much heap use when the key becomes unuseable. 8)

do one of the following:

  • use constants for keys: static final Integer five=new Integer(5) (ugly, eh ;))
  • use an array instead of a HashMap (if your keys are small enough)
  • implement a fast object lookup for int keys yourself
  • find a library that does what you need (e.g. trove has some HashMap implementations using primitive keys.)

If your ints are within the range [-128,+127] then Integer.valueOf( int ) should be used cos that’s backed by a cache (looking at the code of a 1.7 JDK, dunno what the situation is with 1.5).

Can you give us more details, how many keys do you typically hold in the map, and what’s the value range. If performance is critical (you want real time) then you could resort to a big lookup table in the form of an Integer[] array with say 64K entries - again this depends on your value range.

And please don’t use a WeakHashMap! :stuck_out_tongue:

I have not checked it out in detail yet but Colt has the required functionality you need, you can probably just rip the relevant map implementation out:
http://dsd.lbl.gov/~hoschek/colt/.

and also try http://javolution.org/ it has some specialized int Collections

You may have a lot of garbage collected, but are you sure that is causing any slowdown?

Check out this article on how the garbage collecter works: http://www-128.ibm.com/developerworks/java/library/j-jtp01274.html

Oooooo. That Jevolotion looks pretty wicked actually. AND BSD!!! woo! I think some of that is going in JOODE. Our HashMaps are the only source of garbage, from both the entries and the iterators. Where are the custom int hasmaps though?

sorry, wrong pointer. (I mixed something) but there are some collections specialized on primitive types in the net.
eg. the apache.commons package
http://jakarta.apache.org/commons/lang/xref/org/apache/commons/lang/IntHashMap.html uses int keys and Object values…

thanks a lot everybody!

those implementations for primitive types are very useful!

Reusing objects can be useful, when you can apply it. Insted of discarding Integer Objects and creating new ones, you can keep a pool of unused Objects and reuse them if you need one. While the pool keeps hold of objects, the GC wont collect them.

But this cannot be used in every case.

-JAW

This is not a good practice any more. Object creation time is so optimized that creating an object is actually quicker than pulling one out of a pool.

[quote]This is not a good practice any more.
[/quote]
bull****

Have you actually tried??
Don’t believe everything you read.

People: pool your objects

Anybody feeling to say I’m wrong: do the test, and if it doesn’t matter to you, it’s not the bottleneck.

I know what you’re saying (and agree), but ‘People: pool your objects’ is really not good advice unless you’re really having a performance problem caused by object creation/collection.
In most cases, relying on HotSpot’s GC works just fine and leads to cleaner code.

yup, was meant to be a bit provocative, yet I added:
and if it doesn’t matter to you, it’s not the bottleneck.
to make clear sometimes you just shouldn’t care about these things.

next time i’ll be better :slight_smile:

Yeah I know, I just wanted to put your post a bit in perspective :slight_smile:

Not bull, ask Cas. Check out the performance of his games. http://www.puppygames.net

How hard is it to understand?

Don’t point at other projects saying “for them it didn’t matter” without knowing how their code actually works, and where their bottlenecks are.

This sub-forum is littered with posts mentioning the problems of allocating new objects. It’s not even the GC to worry about (usually), simply the allocation process takes more time than fetching an object from a pool, and it definitely not a pointer-shift.

I’ll simply quote my own thread about it… run the benchmarks mentioned in there. (New Object Loop vs Used Object Loop)

Tiny object performance overhead

If it doesn’t convince you… pitty.

Pooling has given a massive performance boost to JOODE.

what is pooling?