【发布时间】:2014-03-03 00:47:27
【问题描述】:
我正在为安卓创建游戏。而且我注意到,每当垃圾收集器启动时,游戏都会出现大量延迟。
App 首次运行时,会创建所有对象并将其添加到 arrayLists 中,如下所示:
br1 = ImgLoader.getResizedBitmap(BitmapFactory.decodeResource(
context.getResources(), R.drawable.branchfl, MainActivity.opt),
MainActivity.height / 12, MainActivity.width / 6);
for (int i = 0; i < 10; ++i) {
branches_available.add(new Sprite("Branch", br1, 0, 0));
}
Sprite 对象由一个位图和几个允许我修改该位图的方法组成。 所以在上面的代码中,我将 10 个 Sprite 存储到一个 ArrayList 中。现在在代码的后面,我需要动态地将所述精灵生成到我的关卡中。所以我所做的就是:
if (rand == 1) {
branches_available.get(0).image = bToAdd;
branches_available.get(0).xPos = (screenWidth - treeWid - bToAdd
.getWidth()) + bToAdd.getWidth() / 18;
branches_available.get(0).yPos = 0 - bToAdd.getHeight();
branches_available.get(0).height = bToAdd.getHeight();
branches_available.get(0).width = bToAdd.getWidth();
branches.add(branches_available.get(0));
branches_available.remove(0);
这会从第一个数组中取出对象并将其添加到第二个数组中。而在draw方法中,只绘制了第二个arrayList。现在,当对象离开屏幕时,我会执行以下操作:
branchesSize = branches.size();
for (int i = 0; i < branchesSize; ++i) {
branches.get(i).move(0, speed);
if (branches.get(i).yPos > screenHeight) {
branches_available.add(branches.get(i));
branches.remove(i);
i--;
branchesSize -= 1;
// System.gc(); // Force Garbage Collection
}
}
因此它们被添加回可用数组中,以便在需要时可以在上述方法中再次重用它们。
尽管这样做,我的应用程序仍然存在大量延迟。可能是因为我从数组中删除了对象?
我做错了什么?
谢谢!
【问题讨论】:
-
我相信这就是为什么某些游戏开发者在本地编写(如果在 Android 上,通过 JNI),因此他们可以手动控制垃圾收集。有些设计可以帮助解决这个问题,但不能完全减轻影响。
-
感谢您的链接。但是我已经广泛研究了这两个来源并将它们应用到我的代码中。无济于事
-
在我的游戏中,(我有 2 个在市场上,一个使用画布,一个使用 OpenGL)我有一个声音管理器,对于画布构建的游戏,我有一个位图/精灵管理器。这会调用 Bitmap.recycle & system..gc 来通知 java 尽快收集垃圾。在位图上我希望完成一段时间,并将我最需要的位图保存在内存中。如果位图已被回收,接下来我需要它,我重新加载它。其他要做的事情是优化您的精灵表以尽可能小(内存方面)。同样在上面我的意思是说,在 Java 中与 c++ 完全相同的事情是不可能的。
-
镜像user2046264的评论:你确定这是GC吗?清单有多大?从
ArrayList中删除元素是O(n),并且由于您在n上循环执行此操作,因此您将获得O(n^2)(慢)性能和ArrayList。您可以考虑使用带有iterator.remove()功能的LinkedList来获取O(1)删除操作:stackoverflow.com/questions/322715/…
标签: java android arrays arraylist bitmap