This question involves memory management in Java for performance reasons: because I am developing this program as an Android Game and memory GC's kill my performance. So I have done a large amount of work so far and it turns out that I am doing a great job of optimizing the memory usage of my game, but I have one problem: iterators!
Here is what I am doing:
- Start game level.
- Start allocation tracker (this way we ignore all of the allocations that will remain for as long as the level runs; I have many objects that only get created once at the beginning of the level and they are not the problem).
- Do a few things in the level and get the allocations.
My allocations are full of this:
466 24 java.util.AbstractList$SimpleListIterator 12 java.util.AbstractList iterator
465 24 java.util.AbstractList$SimpleListIterator 12 java.util.AbstractList iterator
464 24 java.util.AbstractList$SimpleListIterator 12 java.util.AbstractList iterator
463 24 java.util.AbstractList$SimpleListIterator 12 java.util.AbstractList iterator
461 24 java.util.AbstractList$SimpleListIterator 12 java.util.AbstractList iterator
456 24 java.util.ArrayList$ArrayListIterator 12 java.util.ArrayList iterator
454 24 java.util.ArrayList$ArrayListIterator 12 java.util.ArrayList iterator
453 24 java.util.ArrayList$ArrayListIterator 12 java.util.ArrayList iterator
452 24 java.util.ArrayList$ArrayListIterator 12 java.util.ArrayList iterator
So the only objects that are being allocated while my game is running are iterators! Okay, well now to fix it then...what code is causing the problem I asked...here it is:
for (Segment side : listOfSides.getSides()) {
// do stuff
}
Yes, it turns out that for-each syntax calls iterator behind the scenes to populate each element. Which makes perfect sense and exactly what I expected it to do but I did not realise that it could build up so horribly and cause a performance problem for games. If I could get rid of this problem then it would really make my game run like lightning no matter what phone it was on. So my question is: what would you do to make it so that all of these temporary iterators were not created and then immediately discarded resulting in nasty GC runs? Bonus points for doing so in a way that does not make my code completely ugly! (And using ndk on Android is not an option)
P.S. I was thinking that for all of my ArrayLists I could start using the get(int i) function as they are arrays behind the scenes and the integer I would use to index that would be placed on the stack and not the heap. But for the other objects like a HashMap and LinkedList I am not sure what to do.