【发布时间】:2018-11-05 23:39:30
【问题描述】:
我的老师给我的任务是下载一个 2d 游戏并提高应用程序的性能。现在我有点卡住了,我决定下载 Jprofiler 来检查游戏使用的内存等。我看到该应用程序正在使用大量矩形,并且只有当垃圾收集器出现并完成它时它们才会被删除。我的问题是:有没有办法在 GC 出现之前摆脱这些矩形?这是 Jprofiler 扫描的图片。
Sprite 对象有一个 ArrayList 的 Rectangles 作为边界。
tileX = (int)xMap/tileXSize;
tileY = (int)yMap/tileYSize;
accurateX = -(int)xMap%tileXSize;
accurateY = -(int)yMap%tileYSize;
for (int i=tileX; i<tileX+displayX+1 && i<sizeX; i++) {
for (int j=tileY; j<tileY+displayY+1 && j<sizeY; j++) {
Sprite s = spriteMap[j][i];
if (s != null) {
s.act();
// Colisones con los objetos de al lado
if (inMap(i+1,j) && spriteMap[j][i+1] != null) {
if (s.collidesWith(spriteMap[j][i+1], false)) {
s.collision(spriteMap[j][i+1]);
spriteMap[j][i+1].collision(s);
}
}
if (inMap(i,j+1) && spriteMap[j+1][i] != null) {
if (s.collidesWith(spriteMap[j+1][i], false)) {
s.collision(spriteMap[j+1][i]);
spriteMap[j+1][i].collision(s);
}
}
if (inMap(i+1,j+1) && spriteMap[j+1][i+1] != null) {
if (s.collidesWith(spriteMap[j+1][i+1], false)) {
s.collision(spriteMap[j+1][i+1]);
spriteMap[j+1][i+1].collision(s);
}
}
if (s.isToDelete()) {
spriteMap[j][i] = null;
}
}
}
【问题讨论】:
-
实际存在哪些性能问题?矩形在做什么,它们可能都与程序相关,不能收集!?
-
你必须定义你的“性能”概念。垃圾收集器不会运行,因为还有大量未使用的内存,而拥有未使用的内存没有任何优势。这是一个关于 CPU 消耗的好策略。垃圾收集器在不运行时不会浪费 CPU 周期。当您希望应用程序消耗更少的内存时,您可以设置一个上限,例如使用
-Xmx选项。然后,垃圾收集器会更频繁地运行,减少内存消耗,但会增加 CPU 消耗。 -
@JasperHeeren 100 MB 并不是很多内存,除非您在设备上运行。您可以使用池回收矩形,但可能不值得花太多时间。 2 GB 相当于您在 PC 或服务器上花费大约 1 小时的时间。 100 MB 大约需要 3 分钟。
-
如前所述,分配/GC 很可能不是问题所在。 100 MB 是我懒得改变的;忘记记忆,也许速度可以提高。碰撞检测算法(你没有向我们展示)可能是要处理的事情。