我目前正在使用java中的游戏引擎,但是在堆上分配大量对象时我遇到了性能问题,例如
public class GLParticleSystem {
private GLParticle[] particles = new GLParticle[2000];
private int numberOfParticles;
public GLParticleSystem(numberOfParticles) {
this.numberOfParticles = numberOfParticles;
}
public void init() {
for (int i = 0; i < numberOfParticles; i++) {
particles[i] = new GLParticle();
}
}
}
由于分配的剪切水平,上面的代码将在启动时遭受大量的帧丢失,我想知道是否有我遗漏的东西或解决这个问题的一些文字。
更新
我的 GLParticle 类的请求数据成员。
public class GLParticle {
private GLSpriteSheet image = null;
private float x;
private float y;
private float vX;
private float vY;
private float alpha;
private float alphaStep;
private boolean isDead;
private long startTime;
private long lifeTime;
private final float u = 480f;
private final float v = 504f;
}
谢谢Gary
答案 0 :(得分:4)
您可以为GLParticle
的每个成员创建10个单独的2000个数组,并使用Flyweight Pattern。在此实现中,每个GLParticle将其索引传递到GLParticleSystem
的数组,以及包含数组的GLParticleSystem
实例。这稍微麻烦一点,但这是第一个尝试使用大量细粒度对象在CPU周期方面变得过于昂贵的模式。
答案 1 :(得分:1)
您正在init中创建新对象,您可能会发现对象池有用。而不是每次你想要一个对象时创建一个大的集合开始。然后,只要您需要一个对象,就可以获得一个预先分配的对象。
答案 2 :(得分:1)
private static final float U = 480f;
和V
会有所帮助。
看看FutureTask做这些事情。
答案 3 :(得分:1)
虽然我对仅分配2000个对象存在性能问题感到有些惊讶,但我很遗憾地说,没有简单的解决方法可以解决您的问题。 Java,因为它缺少C / C#结构类型,与这些语言相比,在这个用例中不是一种非常有效的语言。您的问题有3种解决方案。
1)在需要之前预先分配对象。虽然它有效,但这不是一个很好的解决方案,因为您必须手动将未使用的对象返回到预分配对象池。
2)鉴于GLParticle是小对象(56字节),如果你的用法允许,它可以被重写为GLParticles类,它存储固定数量的GLParticle对象的数据。
class GLParticles {
private static final float u = 480f, v = 504f;
private GLSpriteSheet[] images;
private float[] x, y, vX, vY, alpha, alphaStep;
private boolean[] isDead;
private long[] startTime, lifeTime;
GLParticles( int size ) {
// allocate arrays here...
}
}
这样既节省空间又分配(和收集)的速度更快。
3)如果您使用的JVM具有这些,则尝试优化托儿所和线程本地GC池的大小。