1

我目前正在使用 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;

}

谢谢加里

4

4 回答 4

4

您可以为 的每个成员创建十个 2000 的单独数组GLParticle,并使用享元模式。在这个实现中,每个 GLParticle 都将其索引传递到GLParticleSystem's 数组中,以及GLParticleSystem包含数组的实例。这稍微麻烦一些,但是当拥有大量细粒度对象在 CPU 周期方面变得过于昂贵时,这是第一个尝试的模式。

于 2012-02-07T00:18:50.550 回答
1

您正在初始化中创建新对象,您可能会发现对象池很有帮助。而不是每次你想要一个对象时都创建一个大集合。然后,每当您需要一个对象时,您就会使用一个预先分配的对象。

http://en.wikipedia.org/wiki/Object_pool_pattern

于 2012-02-07T00:09:58.957 回答
1

private static final float U = 480f;V会有所帮助。

看看 FutureTask 做这些事情。

于 2012-02-07T00:14:34.330 回答
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 有这些,请尝试优化 Nursery 和线程本地 GC 池的大小。

于 2012-02-07T02:52:22.713 回答