Cборка мусора в Java без пауз (HighLoad++ 2013)

37
Сборка мусора в Java без пауз Алексей Рагозин

description

Доклад про паузы при сборке мусора уже был на одной из прошлых конференций HighLoad++. Паузы stop-the-world являются неотъемлемым атрибутом автоматического управления памятью. Или всё-таки их можно избежать? – Можно! Алгоритмы, не требующие пауз для управления памятью, существуют. Существуют и реальные JVM, которые их реализуют. Содержание доклада - Принципы автоматического управления памятью (сборки мусора). - "Метроном" - классический алгоритм сборки мусора без пауз. - С4 - алгоритм сборки мусора Zing JVM (Azul Systems). - Особенности эффективной реализации на x86-архитектуре. - Дополнительные источники проблем: слабые ссылки, фрагментация и прочее.

Transcript of Cборка мусора в Java без пауз (HighLoad++ 2013)

Page 1: Cборка мусора в Java без пауз  (HighLoad++ 2013)

Сборка мусора в Java без пауз

Алексей Рагозин

Page 2: Cборка мусора в Java без пауз  (HighLoad++ 2013)

Сборка мусора

Mark-Sweep Фаза 1 – маркировка достижимых объектов

Фаза 2 – “вычистка” мусора

Copy collector (сборка копированием) Использует две области памяти,

но выполняется в один проход

Mark-Sweep-Compact Mark-Sweep + перемещение живых объектов

Page 3: Cборка мусора в Java без пауз  (HighLoad++ 2013)

Барьеры

Барьеры – специальные процедуры, выполняемые VM при каждом обращении к памяти.

Барьер на запись – при записи указателя в память.

Барьер на чтение – при чтении указателя из памяти.

JIT компиляция позволяет частично сократить нагрузку барьеров за счёт глобальной оптимизации.

Page 4: Cборка мусора в Java без пауз  (HighLoad++ 2013)

Карточный барьер

На каждые N байт памяти – флаг в таблице карт

Любая запись указателя в память, взводит флаг

0xABCD1800

Memory

0xABCD1200

0xABCD1400

0xABCD1600

Dirty cards

0xABCD1200

0xABCD1400

0xABCD1600

Program

entry.next = y;

mark card

write memory

table[n] = entry;

mark card

write memory

0xABCD1200

0xABCD1600

Page 5: Cборка мусора в Java без пауз  (HighLoad++ 2013)

Фоновая маркировка

roo

ts

Page 6: Cборка мусора в Java без пауз  (HighLoad++ 2013)

Фоновая маркировка

roo

ts

Page 7: Cборка мусора в Java без пауз  (HighLoad++ 2013)

Фоновая маркировка

roo

ts

Page 8: Cборка мусора в Java без пауз  (HighLoad++ 2013)

Фоновая маркировка

roo

ts

Page 9: Cборка мусора в Java без пауз  (HighLoad++ 2013)

Фоновая маркировка

roo

ts

Page 10: Cборка мусора в Java без пауз  (HighLoad++ 2013)

Фоновая маркировка

roo

ts

Page 11: Cборка мусора в Java без пауз  (HighLoad++ 2013)

Карточный барьер на запись

Фоновая маркировка с карточным барьером на запись требует 2ух коротких пауз.

Так же, барьер на запись не позволяет реализовать фоновое перемещение объектов.

Можно ли придумать лучший алгоритм, используя барьер на чтение?

Page 12: Cборка мусора в Java без пауз  (HighLoad++ 2013)

Сборка копированием

FROM

TO

roo

ts

Page 13: Cборка мусора в Java без пауз  (HighLoad++ 2013)

Сборка копированием

FROM

TO

roo

ts

FROM

TO

roo

ts

Page 14: Cборка мусора в Java без пауз  (HighLoad++ 2013)

Сборка копированием

FROM

TO

roo

ts

FROM

TO

roo

ts

1

Page 15: Cборка мусора в Java без пауз  (HighLoad++ 2013)

Сборка копированием

FROM

TO

roo

ts

FROM

TO

roo

ts

1 2

Page 16: Cборка мусора в Java без пауз  (HighLoad++ 2013)

Сборка копированием

FROM

TO

roo

ts

FROM

TO

roo

ts

1 2

Page 17: Cборка мусора в Java без пауз  (HighLoad++ 2013)

Сборка копированием

FROM

TO

roo

ts

FROM

TO

roo

ts

1 23

Page 18: Cборка мусора в Java без пауз  (HighLoad++ 2013)

Алгоритм метроном

Алгоритм основан на сборке копированием.

В течение сборки каждый прикладной поток

При чтении указателя, каждый поток проверяет какой области он принадлежит

Если адрес принадлежит “from” пространству, поток выполняет нерекурсивное копирование объекта в “to” и корректирует адрес.

Продлжает работу

Page 19: Cборка мусора в Java без пауз  (HighLoad++ 2013)

Метроном

FROM

TO

roo

ts

1

GC thread

Application thread

V1

Page 20: Cборка мусора в Java без пауз  (HighLoad++ 2013)

Метроном

FROM

TO

roo

ts

1

GC thread

Application thread

V1

Page 21: Cборка мусора в Java без пауз  (HighLoad++ 2013)

Метроном

FROM

TO

roo

ts

1 2

GC thread

Application thread

V1

Page 22: Cборка мусора в Java без пауз  (HighLoad++ 2013)

Метроном

FROM

TO

roo

ts

1 2

GC thread

Application thread

V1

Page 23: Cборка мусора в Java без пауз  (HighLoad++ 2013)

Метроном

FROM

TO

roo

ts

1 2

GC thread

Application thread

V1

3

Page 24: Cборка мусора в Java без пауз  (HighLoad++ 2013)

Метроном

FROM

TO

roo

ts

1 24

GC thread

Application thread

V1

3

Page 25: Cборка мусора в Java без пауз  (HighLoad++ 2013)

Метроном

FROM

TO

roo

ts

1 24

GC thread

Application thread

V1

3

Page 26: Cборка мусора в Java без пауз  (HighLoad++ 2013)

На пути к решению

• Стоимость барьера на чтение

• Время копирования объекта Например, большого массива

• Атомарное обнуление слабых ссылок

• Стоимость сборки мусора Generational vs single spaced

Page 27: Cборка мусора в Java без пауз  (HighLoad++ 2013)

Azul Vega – Java суперкомпьтер

2007 – Vega 2, 7200 series

up to 768 cores

768 GiB RAM

SPARC микорархитектура

hardware assisted garbage collection

Page 28: Cборка мусора в Java без пауз  (HighLoad++ 2013)

LVB - барьер на загрузку указателя

Load Value Barrier • Срабатывает при загрузке указателя из памяти в

регистр

• При срабатывании барьера происходит коррекция источника в памяти

• Прикладной код работает только с проверенными указателями

• При изменении правил барьера потоки ревалидируют указатели в регистрах

Page 29: Cборка мусора в Java без пауз  (HighLoad++ 2013)

Azul JVM

64 битный адрес (хранимый в памяти)

Flags OffsetPage

064

Адрес в памяти

Таблица LVB триггеров

LVB tag

Page 30: Cборка мусора в Java без пауз  (HighLoad++ 2013)

Azul JVM

Доступ в память не требует арифметики указателей

CPU спекулятивно выполняет код параллельно с проверкой барьера

Проверка барьера одним условием

Допольнительные биты используются в процессе маркировки и для работы со слабыми ссылками

Page 31: Cборка мусора в Java без пауз  (HighLoad++ 2013)

Azul JVM

C4 (Continuously Concurrent Compacting Collector)

Инкрементальная сборка мусора регионами

Алгоритм сборки копированием Барьер на чтение обеспечивает фоновую сборку

Generational Регионы классифицируюся как молодые и старые

Фоновая маркировка для оценки “замусоренности” региона

С4 не является алгоритмом реального времени

Page 32: Cборка мусора в Java без пауз  (HighLoad++ 2013)

Azul JVM

http://www.azulsystems.com/sites/default/files/images/c4_paper_acm.pdf

Page 33: Cборка мусора в Java без пауз  (HighLoad++ 2013)

Azul JVM

Mark – фоновая маркировка для выбора регионов подлежащих сборке.

Relocate – копирования объектов.

Remap – рекурсивный обход графа и коррекция ссылок.

Молодые сборки проходят параллельно инкрементальных и включают только relocate фазу.

Page 34: Cборка мусора в Java без пауз  (HighLoad++ 2013)

Azul JVM

2010 Zing 4.0 – virtual appliance

2011 Zing 5.0

x86 (64 бит) архитектура

Linux

Механизм виртуальной памяти используется для эмулации “незначащих” битов адреса.

Page 35: Cборка мусора в Java без пауз  (HighLoad++ 2013)

Azul JVM

3 стратегии копирования

до 256 Kb – копирование байт между страницами

256 Kb – 16 Mb – перемещаются 4k страницы виртуальной памяти с последующей дефрагментацией

Более 16 Mb – не перемещаются 2M страницы виртуальной памяти

Page 36: Cборка мусора в Java без пауз  (HighLoad++ 2013)

Без пауз ≠ Без проблем

“Безпаузный” алгоритм не спасет от утечек памяти

неправильного сайзинга памяти JVM

свопинга

псевдо-свопинга (ожидания записи дискового кэша)

кривых рук (хотя существенно снижает риск)

Page 37: Cборка мусора в Java без пауз  (HighLoad++ 2013)

Спасибо Алексей Рагозин ([email protected])

http://blog.ragozin.info

http://aragozin.timepad.ru