Пул локальных объектов - PullRequest
4 голосов
/ 21 сентября 2010

Проходя книгу Гетца "Параллелизм Java на практике", он приводит аргумент против использования пула объектов (раздел 11.4.7) - основные аргументы:

1) распределение в Java быстрее, чем malloc C 2) потоки, запрашивающие объекты из пула, требуют дорогостоящей синхронизации

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

Есть ли какие-либо проблемы, которые я не вижу при использовании этого подхода? По сути, я разделяю пул объектов между потоками ...

Ответы [ 8 ]

2 голосов
/ 21 сентября 2010

(солнце) GC сканирует живые объекты.Предполагается, что в типичном времени выполнения Java-программ мертвых объектов гораздо больше, чем живых объектов.он помечает живые объекты и удаляет остальные.

Если вы кэшируете много объектов, все они являются живыми.и если у вас есть несколько ГБ таких объектов, GC будет тратить много времени на их тщетное сканирование.длинные GC-паузы могут парализовать ваше приложение.

кэширует что-то, просто чтобы сделать его без мусора, не помогает GC.

это не значит, что кэширование является неправильным.если у вас 15 ГБ памяти, а ваша база данных 10 ГБ, почему бы не кэшировать все в памяти, чтобы ответы быстро высвечивались.обратите внимание, что это для кэширования чего-то, что в противном случае было бы медленным для извлечения.

для предотвращения бесполезного сканирования GC кэша 10G, кэш должен находиться вне контроля GC.Например, используйте memcached, который находится в другом процессе и имеет собственный GC, оптимизированный для кэширования.

последняя новость - Terracotta's BigMemory, который представляет собой чисто Java-решение, которое выполняет аналогичные действия.


Примером локального пула потоков является прямой пул ByteBuffer от Sun. Когда мы вызываем

channel.read(byteBuffer)

, если byteBuffer не «прямой», «прямой» должен быть выделен под капотом, который используется дляПередача данных с ОС. В сетевом приложении такие распределения могут быть очень частыми, что кажется пустым, отбрасывать только что выделенное и немедленно выделять другое в следующем утверждении. Инженеры Sun, очевидно, не доверяют GCнастолько, создал поток локального пула "прямых" байтовых буферов.

2 голосов
/ 21 сентября 2010

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

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

Для более сложных / более крупных объектов пулы объектов могут быть полезны в Java 6, даже если вы используете синхронизацию. например соединение сокета, потока файлов или базы данных.

2 голосов
/ 21 сентября 2010

Если его поток локальный, то вы можете забыть об этом:

2) потоки, запрашивающие объекты из пула, требуют дорогой синхронизации

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

0 голосов
/ 18 декабря 2011

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

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

Бассейны хороши для тяжелых объектов, таких как ByteBuffers, esp. прямые, соединения, сокеты, потоки и т. д. В целом любые объекты, которые требуют не Java-вмешательства.

0 голосов
/ 15 марта 2011

Джошуа Блох, в Effective Java (Second Edition) , говорит:

Второе преимущество статических фабричных методов заключается в том, что, в отличие от конструкторов, они не обязаны создаватьновый объект каждый раз, когда они вызваны.Это позволяет неизменным классам использовать предварительно созданные экземпляры или кэшировать экземпляры по мере их создания и многократно распределять эти экземпляры, чтобы избежать создания ненужных дублирующих объектов.Метод Boolean.valueOf (boolean) иллюстрирует эту технику: он никогда не создает объект.Этот метод может значительно повысить производительность, если часто запрашивать эквивалентные объекты, особенно если эти объекты дороги для создания.

Я бы сказал, что это зависит.Если оно того стоит, сделайте это.

0 голосов
/ 07 ноября 2010

Я бы определенно попробовал. Хотя в настоящее время «общеизвестно», что не следует заботиться о создании объектов, на самом деле производительность пулов объектов и конкретных классов может быть очень высокой. Для среды обработки файлов я получил 5% производительности чтения от пула объектов object [].

Так что попробуйте и время ваших казней, чтобы увидеть, если вы получите что-нибудь.

0 голосов
/ 22 сентября 2010

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

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

0 голосов
/ 21 сентября 2010

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

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