Java-Gaming.org    
Featured games (79)
games approved by the League of Dukes
Games in Showcase (477)
Games in Android Showcase (106)
games submitted by our members
Games in WIP (533)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1] 2
  ignore  |  Print  
  minimizing garbage collection  (Read 15402 times)
0 Members and 1 Guest are viewing this topic.
Offline emzic

Senior Member





« Posted 2007-04-20 19:02:53 »

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!

www.embege.com - personal website
webstart blendinspect - OpenGL BlendingModes visualization.
Offline broumbroum

Junior Member





« Reply #1 - Posted 2007-04-20 23:37:00 »

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. Cool

::::... :..... :::::: ;;;:::™ b23:production 2006 GNU/GPL @ http://b23prodtm.webhop.info
on sf.net: /projects/sf3jswing
Java (1.6u10 plz) Web Start pool
dev' VODcast[/ur
Offline cylab

JGO Ninja


Medals: 38



« Reply #2 - Posted 2007-04-21 01:11:27 »

do one of the following:
- use constants for keys: static final Integer five=new Integer(5) (ugly, eh Wink)
- 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.)



Mathias - I Know What [you] Did Last Summer!
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline mabraham

Junior Member





« Reply #3 - Posted 2007-04-21 15:11:43 »

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!  Tongue
Offline t_larkworthy

Senior Member


Medals: 1
Projects: 1


Google App Engine Rocks!


« Reply #4 - Posted 2007-04-24 17:05:27 »

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/.

Runesketch: an Online CCG built on Google App Engine where players draw their cards and trade. Fight, draw or trade yourself to success.
Offline bienator

Senior Member




OutOfCoffeeException


« Reply #5 - Posted 2007-04-25 09:25:22 »

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

Offline CaptainJester

JGO Knight


Medals: 12
Projects: 2
Exp: 14 years


Make it work; make it better.


« Reply #6 - Posted 2007-04-25 13:32:52 »

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

Quote
The 1.0 and 1.1 JDKs used a mark-sweep collector, which did compaction on some -- but not all -- collections, meaning that the heap might be fragmented after a garbage collection. Accordingly, memory allocation costs in the 1.0 and 1.1 JVMs were comparable to that in C or C++, where the allocator uses heuristics such as "first-first" or "best-fit" to manage the free heap space. Deallocation costs were also high, since the mark-sweep collector had to sweep the entire heap at every collection. No wonder we were advised to go easy on the allocator.

In HotSpot JVMs (Sun JDK 1.2 and later), things got a lot better -- the Sun JDKs moved to a generational collector. Because a copying collector is used for the young generation, the free space in the heap is always contiguous so that allocation of a new object from the heap can be done through a simple pointer addition, as shown in Listing 1. This makes object allocation in Java applications significantly cheaper than it is in C, a possibility that many developers at first have difficulty imagining. Similarly, because copying collectors do not visit dead objects, a heap with a large number of temporary objects, which is a common situation in Java applications, costs very little to collect; simply trace and copy the live objects to a survivor space and reclaim the entire heap in one fell swoop. No free lists, no block coalescing, no compacting -- just wipe the heap clean and start over. So both allocation and deallocation costs per object went way down in JDK 1.2.

Offline t_larkworthy

Senior Member


Medals: 1
Projects: 1


Google App Engine Rocks!


« Reply #7 - Posted 2007-04-25 15:47:54 »

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?

Runesketch: an Online CCG built on Google App Engine where players draw their cards and trade. Fight, draw or trade yourself to success.
Offline bienator

Senior Member




OutOfCoffeeException


« Reply #8 - Posted 2007-04-26 10:46:34 »

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...

Offline emzic

Senior Member





« Reply #9 - Posted 2007-04-29 15:35:54 »

thanks a lot everybody!

those implementations for primitive types are very useful!

www.embege.com - personal website
webstart blendinspect - OpenGL BlendingModes visualization.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline JAW

Senior Member


Medals: 2



« Reply #10 - Posted 2007-05-04 15:15:54 »

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
Offline CaptainJester

JGO Knight


Medals: 12
Projects: 2
Exp: 14 years


Make it work; make it better.


« Reply #11 - Posted 2007-05-04 17:46:36 »

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.

Offline Riven
« League of Dukes »

JGO Overlord


Medals: 743
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #12 - Posted 2007-05-05 01:41:23 »

Quote
This is not a good practice any more.

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.

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings
Offline erikd

JGO Ninja


Medals: 16
Projects: 4
Exp: 14 years


Maximumisness


« Reply #13 - Posted 2007-05-05 01:56:23 »

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.

Offline Riven
« League of Dukes »

JGO Overlord


Medals: 743
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #14 - Posted 2007-05-05 02:00:39 »

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 Smiley

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings
Offline erikd

JGO Ninja


Medals: 16
Projects: 4
Exp: 14 years


Maximumisness


« Reply #15 - Posted 2007-05-05 02:36:43 »

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 Smiley

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

Offline CaptainJester

JGO Knight


Medals: 12
Projects: 2
Exp: 14 years


Make it work; make it better.


« Reply #16 - Posted 2007-05-05 04:07:49 »

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.

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

Offline Riven
« League of Dukes »

JGO Overlord


Medals: 743
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #17 - Posted 2007-05-05 09:05:30 »

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

Quote
Appearantly this object is expensive to construct and/or initialize:

Code:
public class Vec3
{
  public float x,y,z;
}

See my benchmark: compare "new object" (1354ms) and "used object" (447ms).


If it doesn't convince you... pitty.

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings
Offline t_larkworthy

Senior Member


Medals: 1
Projects: 1


Google App Engine Rocks!


« Reply #18 - Posted 2007-05-05 20:29:57 »

Pooling has given a massive performance boost to JOODE.

Runesketch: an Online CCG built on Google App Engine where players draw their cards and trade. Fight, draw or trade yourself to success.
Offline broumbroum

Junior Member





« Reply #19 - Posted 2007-05-06 01:10:27 »

what is pooling?

::::... :..... :::::: ;;;:::™ b23:production 2006 GNU/GPL @ http://b23prodtm.webhop.info
on sf.net: /projects/sf3jswing
Java (1.6u10 plz) Web Start pool
dev' VODcast[/ur
Offline CaptainJester

JGO Knight


Medals: 12
Projects: 2
Exp: 14 years


Make it work; make it better.


« Reply #20 - Posted 2007-05-06 05:06:38 »

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.

I do know how his code works, since he came on the forums and told everyone.  But I guess some people have problems with this and some don't.

Offline princec

JGO Kernel


Medals: 342
Projects: 3
Exp: 16 years


Eh? Who? What? ... Me?


« Reply #21 - Posted 2007-05-06 17:28:52 »

I think what he means to say, and it's been said before, is pool objects that are expensive to construct or destroy. So don't bother pooling little crappy ones like Integers and Particles, it's far more trouble than it's worth.

Cas Smiley

Offline Riven
« League of Dukes »

JGO Overlord


Medals: 743
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #22 - Posted 2007-05-06 17:35:33 »

Cas, you already said that in that other thread:

You can hardly call this an expensive to initialize object:

public class Vec3   {
  public float x,y,z;
}

Yet it slows down the application by factor 3, even if there are LOTS of other calculations doing on, so the benchmark is really not focusing on the allocation, but loses a large chunk of its performance anyway.

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings
Offline princec

JGO Kernel


Medals: 342
Projects: 3
Exp: 16 years


Eh? Who? What? ... Me?


« Reply #23 - Posted 2007-05-06 18:34:20 »

I don't think you'd pool such objects though. What I do is I tend to make a
1  
private static final Vector3f TEMP = new Vector3f();

somewhere in my class and use that over and over for intermediary operations. Not exactly pooling.

Cas Smiley

Offline Jeff

JGO Coder




Got any cats?


« Reply #24 - Posted 2007-05-07 07:58:39 »

So, I read the thread.

Im *really* not sure your testing what you think you are.  Even if the code gets inlined from your method there are still questions of whether or not registers get used as efficiently.

Its really not a proper test because you have multiple variables (allocation and method call) and youa re just assuming that all the resulting imapct is from one of them

To test properly you would need to eliminate the other variants.  In this case, it means writing an "add" mthod that uses pooled objects rather then a new.


Got a question about Java and game programming?  Just new to the Java Game Development Community?  Try my FAQ.  Its likely you'll learn something!

http://wiki.java.net/bin/view/Games/JeffFAQ
Offline swpalmer

JGO Coder




Where's the Kaboom?


« Reply #25 - Posted 2007-07-11 04:32:23 »

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.

Remember that Java allocations must return zeroed memory as far as your object's constructor can tell anyway (any field not explicitly initialized will be set to 0 or null).  That is likely the difference between using 'new' or fetching an old object from a pool. The old object doesn't need to be cleared.

So, sure the allocation step can be just a pointer shift, but the initialization step must be accounted for.

(please excuse the resurrection of the thread)

Offline princec

JGO Kernel


Medals: 342
Projects: 3
Exp: 16 years


Eh? Who? What? ... Me?


« Reply #26 - Posted 2007-07-11 13:56:27 »

In practise, as soon as you reuse an object from a pool you have to re-initialize all its fields anyway. So in the field, this will likely make such an unnoticeable difference it won't matter.

Cas Smiley

Offline swpalmer

JGO Coder




Where's the Kaboom?


« Reply #27 - Posted 2007-07-20 04:09:21 »

My point was that fields are initialized twice for allocation - first they are zeroed, then the constructor can put in the real values.  For the object pool the previous values are only overwritten once with the new real values, the zeroing step is skipped.

Offline cylab

JGO Ninja


Medals: 38



« Reply #28 - Posted 2007-07-20 10:45:49 »

My point was that fields are initialized twice for allocation - first they are zeroed, then the constructor can put in the real values.  For the object pool the previous values are only overwritten once with the new real values, the zeroing step is skipped.

Is this true for all circumstances? I was under the impression, that zeroing is skipped for directly initialized fields (e.g. private int foo=23;) and final fields initialized from the constructor...

Mathias - I Know What [you] Did Last Summer!
Offline keldon85

Senior Member


Medals: 1



« Reply #29 - Posted 2007-07-20 11:57:54 »

Oh gosh, let me try to clear this up. There is an overhead to creating new objects and unfortunately this may not be tackled optimally for a long time to come - however there is potential for the JVM to better analyse the allocations. I created a simple benchmark with a mutable FixedInt class that is a weird hybrid between fixed and floating point. Basically the class allows for easy calculations involving integers with different fixed points automatically, however I found that the following type of loop was slower to a factor of 5 (for divides) and  when replaced with the mutable type.

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
   private static void emptyInt (){
      for (int i = 0; i < MAXVAL; i ++){
         for ( int j = 0; j < MAXVAL; j ++ ) {
         }
      }
   }
   private static void emptyFInt (){
      FixedInt k = new FixedInt(16);
      FixedInt fMaxVal = k.createInt(MAXVAL);
      FixedInt fInc = k.createInt(1);
      for (FixedInt i = k.createInt(0); i.getValue() < fMaxVal.getValue(); i = i.add(fInc)){
         for (FixedInt j = k.createInt(0); j.getValue() < fMaxVal.getValue(); j = j.add(fInc)){
         }
      }
   }


   private static void multiplyInt (){
      int k = 0;
      for (int i = 0; i < MAXVAL; i ++){
         for ( int j = 0; j < MAXVAL; j ++ ) {
            k += k * i * j;
         }
      }
   }
   private static void multiplyFInt (){
      FixedInt k = new FixedInt(16).createInt(0);
     
      FixedInt fMaxVal = k.createInt(MAXVAL);
      FixedInt fInc = k.createInt(1);
      for (FixedInt i = k.createInt(0); i.getValue() < fMaxVal.getValue(); i = i.add(fInc)){
         for (FixedInt j = k.createInt(0); j.getValue() < fMaxVal.getValue(); j = j.add(fInc)){
            k = k.add (k.mul( i.mul (j) ));
         }
      }
     
   }


Is this true for all circumstances? I was under the impression, that zeroing is skipped for directly initialized fields (e.g. private int foo=23;) and final fields initialized from the constructor...
Most likely, however there is still an overhead (as with my example). The example above of k = k.add(k.mul( i.mul (j))); could easily be optimized to creating only one new instance! But this is just the extreme case of using a truly immutable type. The FixedInt i and j were necessary since you would have to convert them anyway so you might as well just have them as FixedInt's

Pages: [1] 2
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

pw (26 views)
2014-07-24 01:59:36

Riven (25 views)
2014-07-23 21:16:32

Riven (19 views)
2014-07-23 21:07:15

Riven (22 views)
2014-07-23 20:56:16

ctomni231 (51 views)
2014-07-18 06:55:21

Zero Volt (46 views)
2014-07-17 23:47:54

danieldean (37 views)
2014-07-17 23:41:23

MustardPeter (40 views)
2014-07-16 23:30:00

Cero (56 views)
2014-07-16 00:42:17

Riven (55 views)
2014-07-14 18:02:53
HotSpot Options
by dleskov
2014-07-08 03:59:08

Java and Game Development Tutorials
by SwordsMiner
2014-06-14 00:58:24

Java and Game Development Tutorials
by SwordsMiner
2014-06-14 00:47:22

How do I start Java Game Development?
by ra4king
2014-05-17 11:13:37

HotSpot Options
by Roquen
2014-05-15 09:59:54

HotSpot Options
by Roquen
2014-05-06 15:03:10

Escape Analysis
by Roquen
2014-04-29 22:16:43

Experimental Toys
by Roquen
2014-04-28 13:24:22
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!