Распределение Java: выделение объектов из ранее существующего / выделенного пула - PullRequest
1 голос
/ 08 ноября 2011

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

Очевидно, что нет способа конкретно указать ссылку на объект на адрес в памяти (для его полей-членов) для настройки пула.Даже если новый объект ссылается на область пула, сам объект все равно должен быть выделен.Как бы вы справились со многими подобными распределениями, не прибегая к собственным библиотекам ОС?

Ответы [ 4 ]

5 голосов
/ 08 ноября 2011

Вы можете попробовать использовать библиотеку Commons Pool .

Тем не менее, если у меня нет доказательств того, что JVM не выполняет то, что мне нужно, я, вероятно, не буду оптимизировать объектсоздание.

1 голос
/ 08 ноября 2011

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

В сети достаточно доказательств , которые показываютпул объектов, независимо от того, насколько малы объекты, полезен для производительности приложения.

Существует два уровня пула, которые вы можете сделать:

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

Как правило, это решение по разработке приложения.

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

1 голос
/ 08 ноября 2011

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

0 голосов
/ 31 марта 2013

@ Дейв и Кейси, вам не нужны никакие доказательства, чтобы показать, что непрерывная структура памяти повышает эффективность кэширования, что является основным узким местом в большинстве приложений ООП, которые требуют высокой производительности, но следуют «слишком идеалистической» траектории разработки ООП.

Люди часто считают, что GC является виновником низкой производительности высокопроизводительных Java-приложений, и после исправления просто оставьте это без фактического профилирования поведения приложения в памяти. Обратите внимание, что инструкции без кэширования по своей природе дороже, чем арифметические инструкции (и становятся все дороже из-за разрыва в доступе к памяти <->). Поэтому, если вы заботитесь о производительности, вам, безусловно, следует заботиться об управлении памятью.

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

Здесь - это SO поток на DOP.

Здесь - это слайд-шоу из отдела исследований и разработок Sony, в котором показана полезность DOP применительно к игре для PlayStation (требуется высокая производительность).

Так как решить проблему, которую Java, вообще, не позволяет выделить кусок памяти? Я предполагаю, что когда программа только начинается, вы можете предположить, что на уже выделенных страницах очень мало внутренней фрагментации. Если у вас теперь есть цикл, который выделяет тысячи или миллионы объектов, они, вероятно, будут все как можно более смежными. Обратите внимание, что вам нужно только удостовериться, что последовательные объекты растягиваются по одной и той же кеш-линии, которая во многих современных системах составляет всего 64 байта. Кроме того, посмотрите на слайды DOP, если вы действительно заботитесь о (памяти) производительности вашего приложения.

Вкратце: всегда выделяйте несколько объектов одновременно (увеличивайте временную локализацию выделения), и, если ваш GC имеет дефрагментацию, запускайте его заранее, иначе попытайтесь сократить такое распределение до начала вашей программы.

Надеюсь, это поможет, -Domi

PS: @Dave, библиотека пула общих ресурсов не распределяет объекты непрерывно. Он только отслеживает распределения, помещая их в эталонный массив, встроенный в стек, связанный список или тому подобное.

...