【发布时间】:2011-01-29 20:33:31
【问题描述】:
我正在为 Android 平台使用 Java 调优交互式游戏的性能。有时,垃圾收集的绘图和交互会出现问题。通常它不到十分之一秒,但有时在非常慢的设备上可能高达 200 毫秒。
我正在使用 ddms 分析器(Android SDK 的一部分)来搜索我的内存分配来自哪里,并将它们从我的内部绘图和逻辑循环中删除。
最严重的违规行为是像这样的短循环,
for(GameObject gob : interactiveObjects)
gob.onDraw(canvas);
每次执行循环时都会分配一个iterator。我现在为我的对象使用数组 (ArrayList)。如果我想要内部循环中的树或哈希,我知道我需要小心甚至重新实现它们,而不是使用 Java 集合框架,因为我负担不起额外的垃圾收集。当我查看优先级队列时,可能会出现这种情况。
我也无法使用Canvas.drawText 显示分数和进度。这很糟糕,
canvas.drawText("Your score is: " + Score.points, x, y, paint);
因为Strings、char 数组和StringBuffers 将全部分配以使其工作。如果您有一些文本显示项目并每秒运行 60 次框架,那么就会开始累加,并会增加您的垃圾收集打嗝。我认为这里最好的选择是保留char[] 数组并手动将int 或double 解码到其中并将字符串连接到开头和结尾。我想知道是否有更清洁的东西。
我知道肯定还有其他人在处理这个问题。您如何处理它?您发现在 Java 或 Android 上以交互方式运行的陷阱和最佳实践是什么?这些 gc 问题足以让我怀念手动内存管理,但不是很多。
【问题讨论】:
-
请参阅 Romain Guy 上次演讲中关于视图失效和 GC 的部分以及分配查看器工具 Googe I/O:code.google.com/events/io/2009/sessions/… 还有官方的 Android 性能指南:developer.android.com/guide/practices/design/performance.html 已经推荐了一段时间由于重复的迭代器分配,避免了标准数组中的增强循环语法。对于组合字符串,请尝试使用 StringBuilder(分配一次并在再次需要时清除它)而不是与 + 连接。
-
我认为去年 google io 上更重要的 Session 是 Chris Pruett 的游戏。它有很多关于实时游戏性能的好线索:code.google.com/intl/de-DE/events/io/2009/sessions/…
-
来自@Moritz 的更新链接:google.com/events/io/2010/sessions/…
标签: java android garbage-collection performance