2012-02-07 79 views
1

我目前工作在Java游戏引擎,在堆中分配大对象集合然而,当我在性能与问题,例如大对象的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; 

} 

感谢加里

+0

GLParticle类有多复杂?你可以发布其数据成员? – dasblinkenlight 2012-02-07 00:06:18

+0

init是在自己的线程中运行的吗? – assylias 2012-02-07 00:15:34

+0

您可以在显示任何图像之前进行初始化* – millimoose 2012-02-07 00:26:25

回答

4

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

+0

非常感谢我设法实现了这个昨晚,并没有分配3000+粒子的问题。 – garyamorris 2012-02-07 13:22:28

1

你快把你的init新对象,你可能会发现对象池是有帮助的。与其每次创建对象时都要创建一个大集合。然后,每当你需要一个对象时,你需要一个预先分配的对象。

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

1

private static final float U = 480f;V将有助于一点点。

看看FutureTask做这样的事情。

1

虽然我有点惊讶你只有分配2000个对象时出现性能问题,但我很抱歉地说你的问题没有简单的解决方法。 Java,因为它缺少C/C#结构类型,与这些语言相比,在这种用例中不是一种非常高效的语言。有3个解决方案可以解决您的问题。

1)在需要它们之前预先分配对象。虽然它起作用,但这不是一个好的解决方案,因为您必须手动将未使用的对象返回到预分配对象池。 2)鉴于GLParticle是一个小对象(56bytes),如果您的使用允许,它可以被重写为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池的大小。