Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

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

485 views

Published on

Каждый новичок знает, что Java делает половину работы за разработчика, в том числе собирает мусор. Очень удобно, не правда ли? Но что, если сборка мусора начинает занимать много времени и к тому же запускается очень часто? Вашему вниманию предоставляется реальный пример оптимизации потребления памяти JVM.

Презентация подготовлена по материалам выступления Евгения Берлога на витебской конференции “Developer's Software Conference” (12.11.2016).

Published in: Software
  • Login to see the comments

  • Be the first to like this

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

  1. 1. ОПТИМИЗАЦИЯ ПОТРЕБЛЕНИЯ ПАМЯТИ В JAVA делаем уборку правильно 12 ноября 2016
  2. 2. Евгений Берлог EPAM Systems Senior Software Engineer 2
  3. 3. 3
  4. 4. 4 ОСОБЕННОСТИ ЗАДАЧИ # REST + MongoDB # Жесткие требования к времени ответа # Stateless
  5. 5. 5 УСЛОВИЯ ТЕСТИРОВАНИЯ # 10000 URL с реального окружения # ~30 вызовов в секунду (реальная нагрузка + 50%) ЗАМЕРЫ УСПЕШНОСТИ # Максимальная пауза # Пропускная способность # Частота Full GC
  6. 6. 7 Исходные замеры Максимальнаяпауза Пропускнаяспособность ЧастотаFullGC 1918мс 99.0% 5развчас
  7. 7. НЕМНОГО ТЕОРИИ
  8. 8. 9 Распределение памяти
  9. 9. 10 Первая сборка
  10. 10. 11 Вторая сборка
  11. 11. 12 Как происходит старение
  12. 12. 13 Большая сборка
  13. 13. ГИПОТЕЗА О СТАРЕНИИ ОБЪЕКТОВ
  14. 14. ГИПОТЕЗА О СТАРЕНИИ ОБЪЕКТОВ Время жизни Размеробъектов
  15. 15. 16 НО РЕАЛЬНАЯ И ТЕОРЕТИЧЕСКАЯ СИТУАЦИИ РАЗЛИЧАЮТСЯ
  16. 16. 17 НО РЕАЛЬНАЯ И ТЕОРЕТИЧЕСКАЯ СИТУАЦИИ РАЗЛИЧАЮТСЯ
  17. 17. КАК МОНИТОРИТЬ СИТУАЦИЮ ?
  18. 18. 19 -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintTenuringDistribution
  19. 19. 20 Вывод детализированного сообщения после каждого запуска Garbage Collector’а. -XX:+PrintGCDetails dsc2016 [PSYoungGen: 1559493K->93696K(1610752K)] 2771413K->1379948K(5106176K), 0.1586049 secs]
  20. 20. 21 -XX:+PrintGCTimeStamps dsc2016 1914.990: [GC [PSYoungGen: 1559493K->93696K(1610752K)] 2771413K->1379948K(5106176K), 0.1586049 secs] Добавление в каждую GC-запись времени относительно старта JVM.
  21. 21. 22 -XX:+PrintTenuringDistribution dsc2016 Desired survivor size 134217728 bytes, new threshold 15 (max 15) Вывод в лог порога старения объектов и необходимого размера Survivor региона.
  22. 22. 23 1914.990: [GC Desired survivor size 134217728 bytes, new threshold 1 (max 15) [PSYoungGen: 1559493K->93696K(1610752K)] 2771413K->1379948K(5106176K), 0.1586049 secs] 1932.209: [GC Desired 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
  23. 23. ADAPTIVE SIZE POLICY
  24. 24. 26 ADAPTIVE SIZE POLICY – это попытка JVM реорганизовать память с целью достичь (#1) уменьшения GC паузы; (#2) увеличения пропускной способности; (#3) уменьшения footprint’а. -XX:AdaptiveSizePolicyOutputInterval=1
  25. 25. 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
  26. 26. 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
  27. 27. 30 Эксперимент #1: Указываем максимальную задержку -XX:GCTimeRatio=999 // по умолчанию 99 -XX:MaxGCPauseMillis=100 // по умолчанию не ограничен
  28. 28. 32 Результат для максимальной задержки Максимальнаяпауза Пропускнаяспособность ЧастотаFullGC 2092мс 99.0% 5развчас
  29. 29. # Выключаем Adaptive Size Policy # Уменьшаем Old Generation # Максимум на Eden # Экспериментально высчитываем Survivor Size 35 Эксперимент #2: Дальше не по правилам
  30. 30. 36 Эксперимент #2: Дальше не по правилам -XX:-UseAdaptiveSizePolicy -Xmx5G -Xms5G -Xmn4300M -XSurvivorRatio=6
  31. 31. 38 Результат c выключенным Adaptive Size Policy Максимальнаяпауза Пропускнаяспособность ЧастотаFullGC 1683мс 99.3% 1разв3.5часов
  32. 32. 39 Максимальнаяпауза Пропускнаяспособность ЧастотаFullGC Базовыенастройки 1918МС 99.0% 5развчас Максимальнаяпауза 2092МС 99.0% 5развчас ВыключенныйASP 1683МС 99.3% 1разв3.5часов Промежуточный результат
  33. 33. - Может пора остановиться?
  34. 34. Concurrent Mark Sweep Collector
  35. 35. 42 Concurrent Mark Sweep (CMS) Collector # То же распределение регионов, что и в Parallel # Тот же алгоритм, что и в Parallel для младшего поколения # Часть работы в старшем поколении выполняется параллельно # Больше footprint, чем в Parallel
  36. 36. 44 Эксперимент #3: Меняем GC! -XX:+UseConcMarkSweepGC -Xmx5G -Xms5G -Xmn4300M -XX:SurvivorRatio=2
  37. 37. 46 Максимальнаяпауза Пропускнаяспособность ЧастотаFullGC 283мс 99.2% 1разв4часа Результат c новым GC
  38. 38. 47 dsc2016 : 1460888K->10522K(1595776K), 0.0049030 secs] 1697910K->247592K(2210176K), 0.0049871 secs] 1195.459: [GC1195.459: [ParNew Desired 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
  39. 39. ... - 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]
  40. 40. ... - 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]
  41. 41. 50 Максимальнаяпауза Пропускнаяспособность ЧастотаFullGC cms 283МС 99.2% 1разв4часа parallel 1681МС 99.3% 1разв3.5часов CMS vs PARALLEL
  42. 42. 51 Почему не G1? > G1 рекомендуется использовать при размерах heap’а от 6ГБ
  43. 43. 53 Эксперимент #4: Используем сборщик G1 -XX:UseG1GC
  44. 44. 55 Максимальнаяпауза Пропускнаяспособность ЧастотаFullGC 351мс 95.9% ? Результат c использованием G1
  45. 45. 57 Максимальнаяпауза Пропускнаяспособность Parallel 1681МС 99.3% G1 351МС 95.9% cms 283МС 99.2% Долгожданный победитель
  46. 46. 58 Максимальнаяпауза ПРопускнаяспособность Parallel 1681МС 99.3% G1 351МС 95.9% cms 283МС 99.2% Долгожданный победитель

×