1

Говорят, что Java позволяет параллельно запускать несколько потоков. В нем также говорится, что создание объекта дешево, поэтому я всегда предпочитаю создавать новый объект для повторного использования. Но, насколько мне известно, объекты создаются в глобальном масштабе (чтобы стать субъектом GC). Теперь возникает чудо, параллелизм остановлен, когда любой из потоков создает объект?Производительность создания параллельных объектов JVM

AFAIK, неуправляемые языки создают объекты в стеке потоков, так что потоки продолжают работать независимо. Все они удаляются после выхода из области подпрограммы. То есть вам не нужно добавлять объекты в глобальный список и останавливать машину для GC позже. Вы можете сделать то же самое с Int/String-подобными неизменяемыми объектами в Java, потому что вы не можете ссылаться на другие объекты, создающие циклические зависимости, для которых требуется очистка GC. Но, afaik, ничего не очищается при выходе процедуры на Java.

+0

Вопрос до сих пор не ясен для меня, можете ли вы объяснить мне немного больше о том, что вы просите в основном? – pbajpai21

ответ

2

Выделение небольших объектов довольно дешево в большинстве случаев из-за TLAB (Thread Local Allocation Buffer). Каждый отдельный поток имеет специальную область в Eden, зарезервированную для локальных распределений потоков, называемых TLAB.

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

 Eden      Survivor 1/2 
------------------------------------------------- 
| T |  | T |    ||  |  | 
| L |  | L |    ||  |  | 
| A |  | A |    ||  |  | 
| B |  | B |    ||  |  | 
| |  | |    ||  |  | 
| 1 |  | 2 |    ||  |  | 
------------------------------------------------- 
^  ^
    |   | 
    reserved for|thread-1 allocations 
       | 
       | 
       reserved for thread-2 allocations 

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

+1

Возможно, стоит добавить, что до тех пор, пока поток не изменяет переменные кучи вне TLAB, для любого другого потока невозможно ссылаться на любой из вновь созданных объектов в этом TLAB. И JVM отслеживает именно это, чтобы включить локальные или мелкие коллекции, которые не требуют остановки всей JVM (для решения второго абзаца вопроса). – Holger

Смежные вопросы