Java临时迭代器正在减慢我的Android游戏速度

Rob*_*oli 12 java performance android memory-management

出于性能原因,这个问题涉及Java中的内存管理:因为我正在开发这个程序作为Android游戏而内存GC会破坏我的性能.所以到目前为止我已经做了大量的工作,事实证明我在优化游戏的内存使用方面做得很好,但我有一个问题:迭代器!

这是我在做的事情:

  1. 开始游戏关卡.
  2. 启动分配跟踪器(这样我们就会忽略在级别运行时将保留的所有分配;我有许多对象只能在级别的开头创建一次并且它们不是问题).
  3. 在关卡中做一些事情并获得分配.

我的分配充满了这个:

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

因此,在我的游戏运行时分配的唯一对象是迭代器!好吧,现在好了解决它...那是什么代码导致我问的问题......这里是:

for (Segment side : listOfSides.getSides()) {
    // do stuff
}
Run Code Online (Sandbox Code Playgroud)

是的,事实证明for-each语法在幕后调用迭代器来填充每个元素.这完全合情合理,正是我的预期,但我没有意识到它可能会如此可怕地构建并导致游戏性能问题.如果我可以摆脱这个问题那么它真的会使我的游戏像闪电一样运行,无论它是什么手机.所以我的问题是:你会做什么来使所有这些临时迭代器都没有被创建然后立即丢弃导致令人讨厌的GC运行?这样做的奖励点不会让我的代码变得丑陋!(在Android上使用ndk不是一个选项)

PS我在想,对于我的所有ArrayLists,我可以开始使用get(int i)函数,因为它们是幕后的数组,我将用于索引的整数将放在堆栈而不是堆上.但对于其他对象,如HashMap和LinkedList,我不知道该怎么做.

Rom*_*Guy 14

使用ArrayList和LinkedList可以使用get(int i)遍历元素(注意它对于LinkedList来说可能很慢,我不知道如何实现get().)这是避免分配迭代器的推荐方法.如果你看一下平台的源代码,你会注意到我们尽量避免使用for-each语法.

对于HashMap,您可以使用entrySet()获取基础集,然后调用toArray(Object [])并传递一个足够大的预分配数组来保存所有值.或者,看看你是否可以使用Android提供的各种SparseArray类.

  • 看看我们的代码库,如果map是空的,似乎entrySet()最多会分配一次.值()和keySet()也是如此.因此,调用这些方法以避免分配是安全的. (2认同)