Затраты на сборку GC для Optional <T>в Java - PullRequest
0 голосов
/ 30 января 2019

Мы все знаем, что каждый объект, выделенный в Java, добавляет вес в будущие циклы сборки мусора, и Optional<T> объекты ничем не отличаются.Мы часто используем эти объекты, чтобы обернуть Nullable, что приводит к более безопасному коду, но какой ценой?

У кого-нибудь есть информация о том, какие дополнительные объекты давления GC добавляют дополнительные объекты по сравнению с простым возвратом нулевых значений и каким воздействиемэто влияет на производительность в системах с высокой пропускной способностью?

1 Ответ

0 голосов
/ 10 февраля 2019

Мы все знаем, что каждый объект, выделенный в Java, добавляет вес в будущие циклы сборки мусора,…

Это звучит как утверждение, которое никто не может отрицать, но давайте посмотрим на фактическую работусборщика мусора, учитывая общие реализации современных JVM и влияние выделенного объекта на него, особенно объектов типа Optional, которые обычно имеют временный характер.

Первая задача сборщика мусора -идентифицировать объекты, которые все еще живы.Название «сборщик мусора» делает акцент на идентификации мусора, но мусор определяется как недостижимые объекты, и единственный способ выяснить, какие объекты недоступны, - это процесс удаления.Таким образом, первая задача решается путем обхода и разметки всех достижимых объектов.Таким образом, стоимость этого процесса не зависит от общего количества выделенных объектов, а зависит только от тех, которые все еще доступны.

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

Следовательно, такой объект, как временный Optional, может не накладывать никакихЗатраты на фактический процесс сбора мусора вообще, если он распределен и отменен между двумя циклами сбора мусора.

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

В реализациях, подобных JVM Hotspot, каждый поток использует буфер локального выделения потока (TLAB) для новых объектов.Как только его TLAB заполнится, он выберет новый из пространства выделения (или Eden space).Если его нет, будет запущена сборка мусора.Теперь маловероятно, что все потоки одновременно попадают в конец своего TLAB.Таким образом, для других потоков, которые еще имеют некоторое пространство в своем TLAB, оставленном на данный момент, не имело бы никакого значения, если бы они выделили еще несколько объектов, все еще вписывающихся в это оставшееся пространство. не каждый выделенный объект влияет на сборку мусора, то есть чисто локальный объект, выделенный потоком, не вызывающим следующий gc, может быть полностью свободным.

Конечно, это не такприменять для выделения большого количества объектов.Выделение множества из них приводит к тому, что поток выделяет больше TLAB и, в конечном итоге, запускает сборку мусора раньше, чем без.Вот почему у нас есть классы, такие как IntStream, позволяющие обрабатывать большое количество элементов без выделения объектов, как это было бы с Stream<Integer>, в то время как нет проблем с предоставлением результата в виде одного OptionalInt экземпляра.Как мы теперь знаем, один временный объект оказывает лишь незначительное влияние на gc, если таковой имеется.

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

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