Выделение памяти Java для больших наборов объектов - PullRequest
1 голос
/ 07 февраля 2012

В настоящее время я работаю над игровым движком в 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 голосов
/ 07 февраля 2012

Вы можете создать десять отдельных массивов по 2000 для каждого члена GLParticle и использовать Flyweight Pattern .В этой реализации каждая GLParticle будет передавать свой индекс в массивы GLParticleSystem вместе с экземпляром GLParticleSystem, который содержит массивы.Это немного более громоздко, но это первый шаблон, который нужно попробовать, когда большое количество мелкозернистых объектов становится слишком дорогим с точки зрения циклов ЦП.

1 голос
/ 07 февраля 2012

Хотя я несколько удивлен тем, что у вас есть проблемы с производительностью при выделении только 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) Попробуйтеоптимизировать размер детского и потокового локальных пулов GC, если они есть у используемой JVM.

1 голос
/ 07 февраля 2012

private static final float U = 480f; и V помогут немного.

Посмотрите на FutureTask для таких вещей.

1 голос
/ 07 февраля 2012

Вы создаете новые объекты в вашем init, вам может пригодиться Object Pooling.Вместо того, чтобы создавать объекты каждый раз, когда вам нужен объект, вы начинаете с большого набора.Затем всякий раз, когда вам нужен объект, вы берете предварительно выделенный объект.

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

...