Java内存分配大对象集

时间:2012-02-07 00:03:37

标签: java memory heap heap-memory large-object-heap

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

4 个答案:

答案 0 :(得分:4)

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

答案 1 :(得分:1)

您正在init中创建新对象,您可能会发现对象池有用。而不是每次你想要一个对象时创建一个大的集合开始。然后,只要您需要一个对象,就可以获得一个预先分配的对象。

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

答案 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池的大小。