Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Allocation free game

My code is basically allocation free, however the GC runs every 30 seconds or so when at 60fps. Checking the app with DDMS for allocation shows there is ALOT of SimpleListIterator being allocated. There is also some stuff being allocated because i use Exchanger.

The SimpleListIterator comes from for each loops for (T obj : objs) {}. I was under the impression that the compilator/translator would optimize those to not use iterators for types that support it (I basically only use ArrayList) but that seems to not be the case.

How can I avoid allocating all these SimpleListIterators? One solution would be to switch to regular for loops for (int i = 0; i < size; ++i) {} but I like for each loops :(

Another way would be to extend ArrayList which returns an Iterator that is only allocated once.

A third way I hacked together is using a static helper function which returns a Collection which is reusing an Iterator. I hacked something like this together but the casting feels very hackish and unsafe. It should be thread safe though as I use ThreadLocal? See below:

public class FastIterator {
    private static ThreadLocal<Holder> holders = new ThreadLocal<Holder>();

    public static <T> Iterable<T> get(ArrayList<T> list) {
        Holder cont = holders.get();

        if (cont == null) {
            cont = new Holder();

            cont.collection = new DummyCollection<T>();
            cont.it = new Iterator<T>();

            holders.set(cont);
        }

        Iterator<T> it = (Iterator<T>) cont.it;
        DummyCollection<T> collection = (DummyCollection<T>) cont.collection;

        it.setList(list);
        collection.setIterator(it);

        return collection;
    }

    private FastIterator() {}

    private static class Holder {
        public DummyCollection<?> collection;
        public Iterator<?> it;
    }

    private static class DummyCollection<T> implements Iterable {
        private Iterator<?> it;

        @Override
        public java.util.Iterator<T> iterator() {
            return (java.util.Iterator<T>) it;
        }

        public void setIterator(Iterator<?> it) {
            this.it = it;
        }
    }

    private static class Iterator<T> implements java.util.Iterator<T> {
        private ArrayList<T> list;
        private int size;
        private int i;

        @Override
        public boolean hasNext() {
            return i < size;
        }

        @Override
        public T next() {
            return list.get(i++);
        }

        @Override
        public void remove() {

        }

        public void setList(ArrayList<T> list) {
            this.list = list;
            size = list.size();
            i = 0;
        }

        private Iterator() {}
    }
}
like image 969
alexanderblom Avatar asked Dec 07 '10 14:12

alexanderblom


People also ask

How do I allocate more memory to a game?

Open your Task Manager and go to the Details tab across the top of the application. You'll see a ton of services and programs running and you need to right-click the specific game you want to allocate more RAM to, then hover over “Set priority”.

How much memory should a mobile game use?

Size of physical RAM: Games often use between ¼ and ½ of the physical RAM amount on the device.

What are the advantages of dynamic memory allocation?

Advantages of Dynamic Memory allocationThis allocation method has no memory wastage. The memory allocation is done at run time. Memory size can be changed based on the requirements of the dynamic memory allocation. If memory is not required, it can be freed.


1 Answers

You should not use for each in Android games. I think this official video talks about that too.

like image 110
mibollma Avatar answered Sep 27 '22 17:09

mibollma