Решение для распределения не во время выполнения - ArrayList - PullRequest
1 голос
/ 08 декабря 2010

Я делаю игру на Java.Мне нужно какое-то решение для моего текущего времени выполнения, вызванное моим ArrayList.Каждую минуту или 30 секунд сборщик мусора начинает работать из-за того, что я вызываю метод draw и updates через эту коллекцию.

Как я могу иметь решение для распределения без времени выполнения?

Заранее спасибо, и, если необходимо, мой код публикуется ниже из моего класса Manager, который содержит ArrayList объектов .:

Некоторый код:

@Override
public void draw(GL10 gl) {
  final int size = objects.size();
  for(int x = 0; x < size; x++) {
    Object object = objects.get(x);
    object.draw(gl);
  }
}

public void add(Object parent) {
  objects.add(parent);
}

     //Get collection, and later we call the draw function from these objects
public ArrayList<Object> getObjects() {
   return objects;
}

public int getNumberOfObjects() {
   return objects.size();
}

Дополнительные пояснения: Причина, по которой я смешиваюсь с этим, заключается в том, что (1) я вижу, что реализация ArrayList медленная и вызывает лаги, и (2) я хочу объединить объекты / компоненты вместе.При запуске вызова обновления из моего Thread-класса он проходит через мою коллекцию, отправляет вещи по дереву / графику с помощью функции обновления Manager.

Когда просматривает проект с открытым исходным кодом,Остров Реплики, я обнаружил, что он использовал альтернативный класс FixedSizeArray, который он написал самостоятельно.Поскольку я не очень хорош в Java, я хотел упростить ситуацию, и теперь я ищу другое решение.И наконец, он объяснил, ПОЧЕМУ он создал специальный класс:

FixedSizeArray - альтернатива стандартной коллекции Java, такой как ArrayList.Он предназначен для обеспечения непрерывного массива фиксированной длины, к которому можно обращаться, сортировать и искать без , требующего выделения во время выполнения .Эта реализация делает различие между «емкостью» массива (максимальное количество объектов, которое он может содержать) и «количеством» массива (текущее количество объектов, вставленных в массив).Такие операции, как set () и remove () могут работать только с объектами, которые были явно добавлены () - ed в массив;то есть индексы, большие, чем getCount (), но меньше, чем getCapacity (), не могут использоваться сами по себе.

Ответы [ 4 ]

4 голосов
/ 08 декабря 2010

Я вижу, что реализация ArrayList идет медленно и вызывает лаги ...

Если вы видите это, вы неверно истолковываете доказательства и делаете необоснованные выводы.ArrayList НЕ является медленным и НЕ вызывает запаздывания ... если только вы не используете класс особенно неоптимальным образом.

Единственный раз, когда список массивов выделяет память, это когда вы создаете список, добавьтедополнительные элементы, скопируйте список или вызовите iterator().

  • При создании списка массивов создаются 2 объекта Java;один для ArrayList и один для его резервного массива.Если вы используете аргумент initialCapacity и задаете соответствующее значение, вы можете договориться о том, чтобы последующие обновления не выделяли память.

  • При добавлении или вставке элемента список массивов может выделить один новый объект.Но это происходит только тогда, когда резервный массив слишком мал, чтобы вместить все элементы, и когда это происходит, новый резервный массив обычно в два раза больше старого.Таким образом, вставка N элементов приведет к выделению максимум log2(N).Кроме того, если вы создаете список массивов с соответствующим initialCapacity, вы можете гарантировать, что при добавлении или вставке будет выделено ноль .

  • При копированиисписок к другому списку или массиву (используя toArray или конструктор копирования) вы получите 1 или 2 выделения.

  • Метод iterator() создает новый объект каждый раз, когда вы вызываете его,Но вы можете избежать этого, выполняя итерации с помощью явной индексной переменной List.size() и List.get(int).(Учтите, что for (E e : someList) { ... } неявно вызывает List.iterator().)

(Внешние операции, такие как Collections.sort, влекут за собой дополнительные выделения, но это не ошибка списка массивов.произойдет с любым типом списка.)

Короче говоря, единственный способ получить большое количество выделений с помощью списка массивов - это создать множество списков массивов или использовать их неразумно.

Класс FixedSizedArray, который вы нашли, звучит как пустая трата времени.Похоже, это эквивалентно созданию ArrayList с начальной емкостью ... с ограничением на то, что сломается , если вы ошибетесь с начальной емкостью.Кто бы ни написал это, вероятно, не очень хорошо понимает коллекции Java.

2 голосов
/ 08 декабря 2010

Не совсем понятно, о чем вы спрашиваете, но:

Если вы знаете во время компиляции, какие объекты должны быть в коллекции, сделайте ее массивом, а не ArrayList, и установите содержимое в блоке инициализации.

Object[] objects = new Object[]{obj1,obj2,obj3};
1 голос
/ 08 декабря 2010

Что вы подразумеваете под "не-распределением времени выполнения"? Я действительно даже не уверен, что вы подразумеваете под "распределением" в этом контексте ... выделение памяти? Это делается во время выполнения, очевидно. Вы явно не имеете в виду какой-либо фиксированный пул объектов, которые известны во время компиляции, так как ваш код позволяет добавлять объекты в ваш список несколькими различными способами (не то, чтобы вы могли выделить для них что-либо во время компиляции даже если бы вы были).

Кроме того, ничто в опубликованном вами коде не будет вызывать сборку мусора сама по себе. Объекты можно собирать мусором только в том случае, если ничто в программе не имеет четкой ссылки на них, а ваш опубликованный код позволяет добавлять объекты только в ArrayList (хотя их можно удалить, вызвав getObjects() и, конечно, удалив из него) , Пока вы не удаляете объекты из списка objects, вы не переназначаете objects, чтобы указывать на другой список, и сам объект, содержащий его, не становится пригодным для сборки мусора, ни один из объектов он также будет доступен для сборки мусора.

Так что, в принципе, нет никакой конкретной проблемы с кодом, который вы разместили, и ваш вопрос не имеет смысла, как задано. Возможно, есть больше деталей, которые вы можете предоставить, или есть лучшее объяснение того, что именно является вашей проблемой и что вы хотите. Если да, попробуйте добавить это к своему вопросу.

Изменить:

Из описания FixedSizeArray и кода, который я рассмотрел в нем, он в значительной степени эквивалентен ArrayList, который инициализируется с определенной емкостью массива (используя конструктор, который принимает int initialCapcacity), за исключением того, что он потерпит неудачу во время выполнения, если что-то попытается добавить к нему, когда его массив заполнен, где ArrayList расширится, чтобы держать больше и продолжать работать просто отлично. Если честно, это кажется бессмысленным занятием, возможно написанным, потому что автор на самом деле не понимал ArrayList.

Обратите также внимание, что его утверждение о "не требующем выделения во время выполнения" немного вводит в заблуждение ... ему, конечно, приходится выделять массив при его создании, но он просто отказывается выделять новый массив, если его первоначальный массив заполняет. Вы можете достичь того же, используя ArrayList, просто задав ему initialCapacity, который по крайней мере достаточно велик, чтобы вместить максимальное количество объектов, которые вы когда-либо добавите к нему. Если вы сделаете это и фактически убедитесь, что никогда не добавляете в него больше этого количества объектов, он никогда не выделит новый массив после его создания.

Тем не менее, все это никак не связано с вашей заявленной проблемой сбора мусора, и ваш код по-прежнему не показывает ничего, что могло бы привести к тому, что огромное количество объектов будет собираться мусором. Если есть какая-либо проблема, она может относиться к коду, который фактически вызывает методы add и getObjects, и к тому, что он делает.

1 голос
/ 08 декабря 2010

Что заставляет вас думать, что вы знаете, что восстанавливает GC? Вы профилировали свою заявку?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...