59
ОПТИМИЗАЦИЯ ПОТРЕБЛЕНИЯ ПАМЯТИ В JAVA делаем уборку правильно 12 ноября 2016

Оптимизация потребления памяти в Java - делаем уборку правильно

Embed Size (px)

Citation preview

Page 1: Оптимизация потребления памяти в Java - делаем уборку правильно

ОПТИМИЗАЦИЯ

ПОТРЕБЛЕНИЯ ПАМЯТИ В JAVAделаем уборку правильно

12 ноября 2016

Page 2: Оптимизация потребления памяти в Java - делаем уборку правильно

Евгений Берлог

EPAM Systems

Senior Software Engineer

2

Page 3: Оптимизация потребления памяти в Java - делаем уборку правильно

3

Page 4: Оптимизация потребления памяти в Java - делаем уборку правильно

4

ОСОБЕННОСТИ ЗАДАЧИ

# REST + MongoDB

# Жесткие требования к времени ответа

# Stateless

Page 5: Оптимизация потребления памяти в Java - делаем уборку правильно

5

УСЛОВИЯ ТЕСТИРОВАНИЯ

# 10000 URL с реального окружения# ~30 вызовов в секунду (реальная нагрузка + 50%)

ЗАМЕРЫ УСПЕШНОСТИ

# Максимальная пауза# Пропускная способность# Частота Full GC

Page 6: Оптимизация потребления памяти в Java - делаем уборку правильно
Page 7: Оптимизация потребления памяти в Java - делаем уборку правильно

7

Исходные замеры

Максимальная пауза Пропускная способность Частота Full GC1918 мс 99.0 % 5 раз в час

Page 8: Оптимизация потребления памяти в Java - делаем уборку правильно

НЕМНОГО ТЕОРИИ

Page 9: Оптимизация потребления памяти в Java - делаем уборку правильно

9

Распределение памяти

Page 10: Оптимизация потребления памяти в Java - делаем уборку правильно

10

Первая сборка

Page 11: Оптимизация потребления памяти в Java - делаем уборку правильно

11

Вторая сборка

Page 12: Оптимизация потребления памяти в Java - делаем уборку правильно

12

Как происходит старение

Page 13: Оптимизация потребления памяти в Java - делаем уборку правильно

13

Большая сборка

Page 14: Оптимизация потребления памяти в Java - делаем уборку правильно

ГИПОТЕЗАО СТАРЕНИИ ОБЪЕКТОВ

Page 15: Оптимизация потребления памяти в Java - делаем уборку правильно

ГИПОТЕЗА О СТАРЕНИИОБЪЕКТОВ

Время жизни

Разм

ер

объект

ов

Page 16: Оптимизация потребления памяти в Java - делаем уборку правильно

16

НО РЕАЛЬНАЯ ИТЕОРЕТИЧЕСКАЯ

СИТУАЦИИ РАЗЛИЧАЮТСЯ

Page 17: Оптимизация потребления памяти в Java - делаем уборку правильно

17

НО РЕАЛЬНАЯ ИТЕОРЕТИЧЕСКАЯ

СИТУАЦИИ РАЗЛИЧАЮТСЯ

Page 18: Оптимизация потребления памяти в Java - делаем уборку правильно

КАКМОНИТОРИТЬСИТУАЦИЮ ?

Page 19: Оптимизация потребления памяти в Java - делаем уборку правильно

19

-XX:+PrintGCDetails

-XX:+PrintGCTimeStamps

-XX:+PrintTenuringDistribution

Page 20: Оптимизация потребления памяти в Java - делаем уборку правильно

20

Вывод детализированного сообщения после каждого

запуска Garbage Collector’а.

-XX:+PrintGCDetails

dsc2016

[PSYoungGen: 1559493K->93696K(1610752K)] 2771413K->1379948K(5106176K), 0.1586049 secs]

Page 21: Оптимизация потребления памяти в Java - делаем уборку правильно

21

-XX:+PrintGCTimeStamps

dsc2016

1914.990: [GC[PSYoungGen: 1559493K->93696K(1610752K)] 2771413K->1379948K(5106176K), 0.1586049 secs]

Добавление в каждую GC-запись времени

относительно старта JVM.

Page 22: Оптимизация потребления памяти в Java - делаем уборку правильно

22

-XX:+PrintTenuringDistribution

dsc2016

Desired survivor size 134217728 bytes, new threshold 15 (max 15)

Вывод в лог порога старения объектов и необходимого размера Survivor региона.

Page 23: Оптимизация потребления памяти в Java - делаем уборку правильно

23

1914.990: [GCDesired survivor size 134217728 bytes, new threshold 1 (max 15)[PSYoungGen: 1559493K->93696K(1610752K)] 2771413K->1379948K(5106176K), 0.1586049 secs] 1932.209: [GCDesired survivor size 136839168 bytes, new threshold 1 (max 15)[PSYoungGen: 1569792K->53234K(1611776K)] 2856044K->1408182K(5107200K), 0.1083012 secs]

dsc2016

-XX:+PrintGCDetails-XX:+PrintGCTimeStamps-XX:+PrintTenuringDistribution

Page 24: Оптимизация потребления памяти в Java - делаем уборку правильно
Page 25: Оптимизация потребления памяти в Java - делаем уборку правильно

ADAPTIVE SIZE POLICY

Page 26: Оптимизация потребления памяти в Java - делаем уборку правильно

26

ADAPTIVE SIZE POLICY – это попытка

JVM реорганизовать память с целью достичь

(#1) уменьшения GC паузы;

(#2) увеличения пропускной способности;

(#3) уменьшения footprint’а.

-XX:AdaptiveSizePolicyOutputInterval=1

Page 27: Оптимизация потребления памяти в Java - делаем уборку правильно

27

ЛОГИ GC С ВКЛЮЧЕННЫМ ASP

UseAdaptiveSizePolicy actions to meet *** reduced footprint ***GC overhead (%)

Young generation: 1.26 (attempted to shrink)Tenured generation: 0.00 (no change)Tenuring threshold: (attempted to decrease to balance GC costs) = 2

dsc2016

Page 28: Оптимизация потребления памяти в Java - делаем уборку правильно

28

ЛОГИ GC С ВКЛЮЧЕННЫМ ASP

UseAdaptiveSizePolicy actions to meet *** reduced footprint ***GC overhead (%)

Young generation: 1.26 (attempted to shrink)Tenured generation: 0.00 (no change)Tenuring threshold: (attempted to decrease to balance GC costs) = 2

dsc2016

Page 29: Оптимизация потребления памяти в Java - делаем уборку правильно
Page 30: Оптимизация потребления памяти в Java - делаем уборку правильно

30

Эксперимент #1:Указываем максимальную задержку

-XX:GCTimeRatio=999// по умолчанию 99

-XX:MaxGCPauseMillis=100// по умолчанию не ограничен

Page 31: Оптимизация потребления памяти в Java - делаем уборку правильно
Page 32: Оптимизация потребления памяти в Java - делаем уборку правильно

32

Результат для максимальной задержки

Максимальная пауза Пропускная способность Частота Full GC2092 мс 99.0 % 5 раз в час

Page 33: Оптимизация потребления памяти в Java - делаем уборку правильно
Page 34: Оптимизация потребления памяти в Java - делаем уборку правильно
Page 35: Оптимизация потребления памяти в Java - делаем уборку правильно

# Выключаем Adaptive Size Policy

# Уменьшаем Old Generation

# Максимум на Eden

# Экспериментально высчитываем Survivor Size

35

Эксперимент #2:Дальше не по правилам

Page 36: Оптимизация потребления памяти в Java - делаем уборку правильно

36

Эксперимент #2:Дальше не по правилам

-XX:-UseAdaptiveSizePolicy

-Xmx5G -Xms5G

-Xmn4300M

-XSurvivorRatio=6

Page 37: Оптимизация потребления памяти в Java - делаем уборку правильно
Page 38: Оптимизация потребления памяти в Java - делаем уборку правильно

38

Результат c выключенным Adaptive Size Policy

Максимальная пауза Пропускная способность Частота Full GC1683 мс 99.3 % 1 раз в 3.5 часов

Page 39: Оптимизация потребления памяти в Java - делаем уборку правильно

39

Максимальная пауза Пропускная способность Частота Full GC

Базовые настройки 1918 МС 99.0 % 5 раз в час

Максимальная пауза 2092 МС 99.0 % 5 раз в час

Выключенный ASP 1683 МС 99.3 % 1 раз в 3.5 часов

Промежуточный результат

Page 40: Оптимизация потребления памяти в Java - делаем уборку правильно

- Может пора остановиться?

Page 41: Оптимизация потребления памяти в Java - делаем уборку правильно

Concurrent Mark Sweep Collector

Page 42: Оптимизация потребления памяти в Java - делаем уборку правильно

42

Concurrent Mark Sweep (CMS) Collector

# То же распределение регионов, что и в Parallel

# Тот же алгоритм, что и в Parallel для младшегопоколения

# Часть работы в старшем поколениивыполняется параллельно

# Больше footprint, чем в Parallel

Page 43: Оптимизация потребления памяти в Java - делаем уборку правильно
Page 44: Оптимизация потребления памяти в Java - делаем уборку правильно

44

Эксперимент #3:Меняем GC!

-XX:+UseConcMarkSweepGC-Xmx5G -Xms5G -Xmn4300M-XX:SurvivorRatio=2

Page 45: Оптимизация потребления памяти в Java - делаем уборку правильно
Page 46: Оптимизация потребления памяти в Java - делаем уборку правильно

46

Максимальная пауза Пропускная способность Частота Full GC283 мс 99.2 % 1 раз в 4 часа

Результат c новым GC

Page 47: Оптимизация потребления памяти в Java - делаем уборку правильно

47

dsc2016

: 1460888K->10522K(1595776K), 0.0049030 secs] 1697910K->247592K(2210176K), 0.0049871 secs]1195.459: [GC1195.459: [ParNewDesired survivor size 74252288 bytes, new threshold 15 (max 15)- age 1: 690016 bytes, 690016 total- age 2: 148448 bytes, 838464 total- age 3: 751056 bytes, 1589520 total...- age 13: 82512 bytes, 3801784 total- age 14: 607816 bytes, 4409600 total- age 15: 1348728 bytes, 5758328 total

Анализ логов CMS

Page 48: Оптимизация потребления памяти в Java - делаем уборку правильно

...- age 13: 82512 bytes, 3801784 total- age 14: 607816 bytes, 4409600 total- age 15: 1348728 bytes, 5758328 total

15299.307: [GC [1 CMS-initial-mark: 581268K(839680K)] 1241313K(4142080K), 0.2830091 secs]15306.520: [GC[YG occupancy: 1031447 K (3302400 K)]15306.520: [Rescan (parallel) , 0.2487740 secs]15306.769: [weak refs processing, 0.0012183 secs]15306.770: [scrub string table, 0.0012292 secs] [1 CMS-remark: 581268K(839680K)] 1612715K(4142080K), 0.2518813 secs]

Page 49: Оптимизация потребления памяти в Java - делаем уборку правильно

...- age 13: 82512 bytes, 3801784 total- age 14: 607816 bytes, 4409600 total- age 15: 1348728 bytes, 5758328 total

15299.307: [GC [1 CMS-initial-mark: 581268K(839680K)] 1241313K(4142080K), 0.2830091 secs]15306.520: [GC[YG occupancy: 1031447 K (3302400 K)]15306.520: [Rescan (parallel) , 0.2487740 secs]15306.769: [weak refs processing, 0.0012183 secs]15306.770: [scrub string table, 0.0012292 secs] [1 CMS-remark: 581268K(839680K)] 1612715K(4142080K), 0.2518813 secs]

Page 50: Оптимизация потребления памяти в Java - делаем уборку правильно

50

Максимальная пауза Пропускная способность Частота Full GCcms 283 МС 99.2 % 1 раз в 4 часаparallel 1681 МС 99.3 % 1 раз в 3.5 часов

CMS vs PARALLEL

Page 51: Оптимизация потребления памяти в Java - делаем уборку правильно

51

Почему не G1?

> G1 рекомендуется использовать при размерах heap’а от 6ГБ

Page 52: Оптимизация потребления памяти в Java - делаем уборку правильно
Page 53: Оптимизация потребления памяти в Java - делаем уборку правильно

53

Эксперимент #4:Используем сборщик G1

-XX:UseG1GC

Page 54: Оптимизация потребления памяти в Java - делаем уборку правильно
Page 55: Оптимизация потребления памяти в Java - делаем уборку правильно

55

Максимальная пауза Пропускная способность Частота Full GC351 мс 95.9 % ?

Результат c использованием G1

Page 56: Оптимизация потребления памяти в Java - делаем уборку правильно
Page 57: Оптимизация потребления памяти в Java - делаем уборку правильно

57

Максимальная пауза Пропускная способностьParallel 1681 МС 99.3 %G1 351 МС 95.9 %cms 283 МС 99.2 %

Долгожданный победитель

Page 58: Оптимизация потребления памяти в Java - делаем уборку правильно

58

Максимальная пауза ПРопускная способностьParallel 1681 МС 99.3 %G1 351 МС 95.9 %cms 283 МС 99.2 %

Долгожданный победитель

Page 59: Оптимизация потребления памяти в Java - делаем уборку правильно