【问题标题】:Java Memory Allocation of large object sets大对象集的Java内存分配
【发布时间】:2012-02-28 11:06:35
【问题描述】:

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

}

谢谢加里

【问题讨论】:

  • GLParticle 类有多复杂?你能发布它的数据成员吗?
  • init 是否在自己的线程中运行?
  • 你能在任何图像显示之前进行初始化吗?
  • GLParticle 的 2k 个对象什么都不是,问题不在于分配本身。我敢打赌你初始化 GLSpriteSheet 这将是主要问题,其余的真的没什么
  • (您可以从 cmets 推断,有很多方法可以减轻您所描述的内容。)

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


【解决方案1】:

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

【讨论】:

  • 非常感谢,我昨晚成功实现了这个,分配 3000 多个粒子没有问题。
【解决方案2】:

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

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

【讨论】:

    【解决方案3】:

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

    看看 FutureTask 做这些事情。

    【讨论】:

      【解决方案4】:

      虽然我对仅分配 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 池的大小。

      【讨论】:

        猜你喜欢
        • 2015-10-15
        • 1970-01-01
        • 1970-01-01
        • 2013-01-21
        • 2014-03-17
        • 2011-09-13
        • 1970-01-01
        • 1970-01-01
        • 2010-09-24
        相关资源
        最近更新 更多