【发布时间】:2014-12-13 17:34:01
【问题描述】:
我最近使用 LibGdx 实现了一个网格系统(空间分区)来优化碰撞检测的性能。我在板上生成了 2000 个实体,让它们四处移动,重新计算它们在网格上的新图块位置,并在必要时将实体转移到正确的集合中。
问题:
GC_FOR_ALLOC freed 3068K (65765), 45% free 3925K/7124K, paused 36ms, total 36ms
在 Android 上大约每秒发生一次,导致渲染出现卡顿。
代码:
这是由每个实体运行的:
if(newgridy!=currentgridy||newgridx!=currentgridy){
try {
my_tile.remove(this);
my_tile = grid[newgridy][newgridx];
my_tile.add(this);
}catch (ArrayIndexOutOfBoundsException e){
}
}
newgridy,newgridx,currentgridy,currentygridx 是平铺坐标(不是渲染坐标)
my_tile 是一个数组列表
grid 是 ArrayLists 的二维数组
我的尝试:
我知道这是有问题的代码块,因为当我将其注释掉时,GC 调用就会消失。
我认为重复的 remove 和 add 调用会导致内存碎片化,并且 ArrayList 变得太大而无法放入内存中的任何连续位置,因此当我的 Entities 进入新的 tile 时,GC 必须压缩。我想我应该为每个图块预先分配空间,但每个图块可能同时包含 1000 多艘船,有时甚至是完全空的。然后我将不得不分配 1000 以适应它已满时的情况,但如果瓷砖是空的,那将是巨大的浪费。
问题
内存碎片是我的问题吗?如果是这样,Java 中是否有一个可以不连续的集合?或者其他解决方法?
是否会切换到四叉树以获得优化帮助?
抱歉有多个问题,有点宽泛。
【问题讨论】:
标签: java android performance data-structures garbage-collection