分配免费游戏

ale*_*lom 5 java android opengl-es

我的代码基本上是免费分配的,但是当60fps时,GC每30秒运行一次.使用DDMS检查应用程序以进行分配显示有很多SimpleListIterator被分配.因为我使用了也有一些东西被分配Exchanger.

SimpleListIterator来自每个循环for (T obj : objs) {}.我的印象是编译器/翻译器会优化那些不使用迭代器来支持它的类型(我基本上只使用ArrayList),但似乎并非如此.

我怎样才能避免分配所有这些SimpleListIterators?一种解决方案是切换到常规循环,for (int i = 0; i < size; ++i) {}但我喜欢每个循环:(

另一种方法是扩展ArrayList,它返回一个Iterator只分配一次的ArrayList .

我一起攻击的第三种方法是使用一个静态辅助函数,它返回一个Collection重用的函数Iterator.我一起攻击了这样的东西,但铸件感觉非常黑暗和不安全.虽然我使用它应该是线程安全的ThreadLocal吗?见下文:

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() {}
    }
}
Run Code Online (Sandbox Code Playgroud)

mib*_*lma 4

您不应该在 Android 游戏中使用 for every。我认为这个官方视频也谈到了这一点。