Секреты сборки мусора в Java (Алексей Рагозин)

Post on 22-May-2015

3.217 views 4 download

Tags:

Transcript of Секреты сборки мусора в Java (Алексей Рагозин)

Секреты сборки мусора в Java

Алексей Рагозинalexey.ragozin@gmail.com

О чём этот доклад?• Обзор проблемы автоматического

управления памятью• Stop-the-world паузы – причины• Сборка мусора в современных JVM

Сборка мусораЯзыки использующие автоматическое управление памятью Java, JavaScript, Erlang, Haskell, Python, PHP, C#, Ruby, Perl, SmallTalk, OCaml, List, Scala, ML, Go, D, … … and counting

Языки не использующие автоматическое управление памятью C, C++, Pascal/Delphi, Objective-C Что я забыл?

Способы сборки мусораМусор – структура данных (объект) в памяти не достижимый из программного кода.

Подсчёт ссылокТранзитивное замыкание ссылок Вообще не собирать

Подсчёт ссылок+ Просто+ Не требует пауз для сбора мусора– Не очищает циклические графы– Дополнительные 15-30% нагрузки CPU– Плохо сочетается с много поточностью

Транзитивное замыкание ссылок• Корневой набор ссылок

Статические переменные Локальные переменные

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

Следовательно, приложение должно быть остановлено пока идёт сборка мусора.

Алгоритмы сборки мусора• Mark-Sweep-Compact

Фаза 1 – маркировка достижимых объектов Фаза 2 – “вычистка” мусора

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

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

Трёх цветная маркировкаroots

Трёх цветная маркировкаroots

roots

Трёх цветная маркировкаroots

roots

Трёх цветная маркировкаroots

roots

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

FROM

TO

roots

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

FROM

TO

roots

FROM

TO

roots

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

FROM

TO

roots

FROM

TO

roots

1

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

FROM

TO

roots

FROM

TO

roots

1 2

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

FROM

TO

roots

FROM

TO

roots

1 2

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

FROM

TO

roots

FROM

TO

roots

1 23

Экономика сборки мусораS – объём кучиL – объём живых объектов

Copy collection ЭффективностьMark-Sweep Эффективность

L

LSc

S

LSc

L

LSc

21

Объём мусора в куче

Слабая гипотеза о поколенияхПостулаты Большинство объектов умирают молодыми Число ссылок на молодые объекты мало

СледствиеЕсли хранить молодые и старые объекты отдельно, можно

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

Демография объектов в куче

См

ертн

ость

айт/

с)

Возраст объектов

Период молодой сборки

Период старой сборки

Generational collection Молодое поколение

Сборщик настроен на пропускную способность Старое поколение

Сборщик настроен на эффективное использование памяти Продвижение (promotion) объектов в старое поколение

Сборщик молодого поколения копирует живые объекты в старое поколение после достижения “зрелого” возраста

Generational collectionКак получить все указатели из старого поколения на молодое?Ответ - write barrier Каждый раз при записи указателя в память в “старом” пространстве, срабатывает барьер

Молодая сборка HotSpot JVMEden S1 S2 Tenured

Dirty cards

Collect roots for young GCScan stack tracesScan dirty pages in old space

Сбор Сбор ““корневыхкорневых”” ссылок ссылок

Молодая сборка HotSpot JVMEden S1 S2 Tenured

Dirty cards

Collect roots for young GCClean cardsRecursive copy of live objects (only live objects are traversed)

Копирование живых объектовКопирование живых объектов

Молодая сборка HotSpot JVMEden S1 S2 Tenured

Dirty cards

Сборка законченаСборка закончена

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

Stop-the-world паузы• Изменение графа объектов во время обхода

может привести к пропуску достижимых объектов

• Большинство managed runtimes может перемещать объекты только в режиме паузы

Stop-the-world паузыПараллельные (parallel) алгоритмы Используют несколько потоков чтобы сократить время пауз

Конкурентные (concurrent) алгоритмы Выполняют большую часть работы в фоновом режиме (без STW пауз)

Инкрементальные алгоритмы Много маленьких STW вместо одной длитетьной

Concurrent markingПроблема Граф объектов меняется по мере обхода * * Даже в функциональных языках могут выполняться отложенные вычисления, меняющие граф

Решение write-barrier – отслеживать ссылки изменившиеся за время обхода

Concurrent marking Card marking write barrier

HotSpot CMS, JRockit, IBM J9 Snapshot-at-the-beginning (SATB) write barrier

HotSpot G1 Read barrier (помечать объекты как живые при

чтении) Azul Zing JVM

SATB write barrier (G1)

A B C D

GC A

C

SATB write barrier (G1)

A B C D

GC C

D

STAB write barrier (G1)

A B C D

GC C

D

Reference queue: B D

STAB write barrier (G1)

A B C D

GC C

D

SATB write barrier (G1)

A B C D

GC D

D

SATB write barrier (G1)

A B C D

GC

Reference queue: B D

SATB write barrier (G1)

A B C D

GC

Reference queue:

B

D

empty

Card marking write barrier [пауза] Сбор корневых ссылок [фон] Обход графа объектов [фон] Перемаркирова “грязных” страниц [паузa] Финальная перемаркирова

Перемещение объектовБольшинство JVM не могут перемещать объекты без STW паузы.

Цель – уменьшение длительности паузПараллельная обработка (задействовать все ядра)Инкрементальное уплотнение (чаще, но короче)Не уплотнять – опасность фрагментации

Oracle HotSpotDefault (serial) collector Young: Serial copy collector, Old: serial MSC

Parallel scavenge / Parallel old GC Young: Parallel copy collector, Old: serial MSC or parallel MSC

Concurrent mark sweep (CMS) Young: Serial or parallel copy collector, Old: concurrent mark sweep

G1 (garbage first) Young: Copy collector (region based) Old: Incremental MSC

http://aragozin.blogspot.com/2011/09/hotspot-jvm-garbage-collection-options.html

Oracle’s HotSpot JVMYoung collector Old collector JVM option Serial (DefNew) Serial Mark-Sweep-Compact -XX:+UseSerialGC

Parallel scavenge (PSYoungGen) Serial Mark-Sweep-Compact (PSOldGen) -XX:+UseParallelGC

Parallel scavenge (PSYoungGen) Parallel Mark-Sweep-Compact (ParOldGen) -XX:+UseParallelOldGC

Serial (DefNew) Concurrent Mark Sweep -XX:+UseConcMarkSweepGC -XX:-UseParNewGC

Parallel (ParNew) Concurrent Mark Sweep -XX:+UseConcMarkSweepGC -XX:+UseParNewGC

G1 -XX:+UseG1GC

http://aragozin.blogspot.com/2011/09/hotspot-jvm-garbage-collection-options.html

Oracle JRockit-Xgc: option Generational Mark Sweep/Compact

genconcon or gencon Yes concurrent incrementalsingleconcon or singlecon No concurrent incremental

genconpar Yes concurrent parallelsingleconpar No concurrent parallelgenparpar or genpar Yes parallel parallelsingleparpar or singlepar No parallel parallel

genparcon Yes parallel incrementalsingleparcon No parallel incremental

http://aragozin.blogspot.com/2011/07/jrockit-gc-in-action.html

IBM J9-Xgcpolicy:optthruput Одно поколение, stop-the-world сборщик

-Xgcpolicy:optavgpause Одно поколение, частично конкурентный сборщик

-Xgcpolicy:gencon Два поколения, частично конкурентный сборщик

Azul Zing• Два поколения• Молодое поколение – конкурентный mark-sweep-compact (MSC)• Старое поколение – конкурентный mark-sweep-compact (MSC)

Azul Zing выполняет перемещение объектов (уплотнение памяти) без останова приложения. Ни одна из фаз сборки мусора не требует STW паузы.

Секрет – read barrier.

Масштабируемость JVMМожет ли JVM работать с большим объёмом памяти (16GiB и более) без “фризов”?

Ответ да, если приложение удовлетворяет постулатам гипотезы о поколениях.

Рецепт работы без пауз• HotSpot JVM• CMS (Concurrent Mark Sweep) сборщик мусора• ТюнингРезультат• Паузы не более 150ms на 32GiB хипа

HotSpot CMS сборщик Сборка молодого поколения копированием Не перемещает объекты в старом поколении Статистические методы борьбы с фрагментацией Две дополнительные STW фазы

initial-mark, remark Вся остальная работа происходит в фоне

Длительность пауз CMS сборщика

Можно лучше – OpenJDK патч

http://aragozin.blogspot.com/2011/07/openjdk-patch-cutting-down-gc-pause.html

Сборка мусора в JVM Сборка мусора не чёрная магия Каждое приложение индивидуально Приложение не должно мешать сборщику мусора JVM может работать без пауз

(с паузами не более 100-200ms) Автоматическое управление памятью не

универсально(Проблемные приложения: HBase, Cassandra)

Альтернативыjava.nio.ByteBuffer.allocateDirect()Pro• Memory is allocated out of heap• Memory is deallocated when ByteBuffer is collected• Cross platform, native javaCon• Fragmentation of non-heap memory• Memory is deallocated when ByteBuffer is collected• Complicated multi thread programming• -XX:MaxDirectMemorySize=<value>

АльтернативыReal Time System JavaИерархия регионов памяти• Объекты выделяются в выбранном регионе• Локальные и “бессмертные” регионы не собираются• Локальные регионы освобождаются целиком• Глобальные объекты не могу ссылаться на локальные

АльтернативыUnsafe javasun.misc.Unsafe• Unsafe.allocateMemory(…)• Unsafe.reallocateMemory(…)• Unsafe.freeMemory(…)

Спасибо

Алексей Рагозин alexey.ragozin@gmail.com

http://aragozin.blogspot.com- мои статьи о JVM и не только