59

Java Platform Performance BoF - Aleksey Shipilëv · – 2x2 Intel i5 2.6 Ghz, Ubuntu 10.10 i686, JDK 6u25 • Три варианта эксперимента: – 1 экземпляр

  • Upload
    others

  • View
    4

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Java Platform Performance BoF - Aleksey Shipilëv · – 2x2 Intel i5 2.6 Ghz, Ubuntu 10.10 i686, JDK 6u25 • Три варианта эксперимента: – 1 экземпляр

2 copy JavaTechDays 2011 Oracle Corporation

Java Platform Performance BoFо чём у нас

bull Отвечаем на вопросыndash В основном предварительно собранные на Хабрахабре и ru_javandash Есть возможность задать вопрос прямо здесь

bull Пишем на бумажке передаём вперёд )

bull Здесь и сейчасndash Performance Engineeringndash Benchmarkingndash New features compatibility support and beyondndash Concurrency and synchronizationndash JITndash Startup

bull Не здесь или не сейчас а на других сессияхndash ldquoJDK7 InvokeDynamicrdquo стенды 1430ndash ldquoJDK7 and Java SE 7rdquo Конгресс-холл 1720ndash ldquoДиагностика проблем и настройка GC []rdquo Конгресс-холл 1820

4 copy JavaTechDays 2011 Oracle Corporation

Performance Engineeringабстрактно и отлично об отличиях в абстракциях

bull Computer Science rarr Software Engineeringndash Строим приложения по функциональным требованиямndash В большой степени абстрактно в ldquoидеальном миреrdquo

bull Теоретически неограниченная свобода ndash искусствоbull Можно строить воздушные зАмки

ndash Рассуждения при помощи формальных методов

bull Software Performance Engineeringndash ldquoReal world strikes backrdquo

bull Алгоритмическая сложность всей системы целикомbull Физические ограничения на скорость выполнения

ndash Исследуем взаимодействие софта с железом на типичных данныхndash Естественно-научные методы

bull Основываемся на эмпирических данных

5 copy JavaTechDays 2011 Oracle Corporation

Performance Engineeringпервый шаг

bull Классические ошибки первого шагаndash ldquoя вижу что метод foo() реализован неэффективноrdquondash ldquoпо профилю видно что метод bar() ndash самый горячий и занимает 5rdquo

ndash ldquoпо-моему у нас тормозит БД и необходимо перейти с DBX на DB

Yrdquo

bull Правильный первый шагndash Необходимо выбрать метрику

bull opssec transactionssecbull время исполненияbull время отклика

ndash Убедиться в корректности метрикиbull релевантна (учитывает реальный сценарий работы приложения)bull повторяема

ЦЕЛЬ rarr улучшение метрики

7 copy JavaTechDays 2011 Oracle Corporation

Performance Engineeringанализ узких мест

bull Что ограничивает скорость работы приложения

bull CPUbull Ядро ОСbull IO (Сеть Диск)

9 copy JavaTechDays 2011 Oracle Corporation

Performance Engineeringанализ узких мест (tips)

bull Низкая утилизация CPUndash Высокая дисковая сетевая активностьndash Конфликт блокировокndash Конфликт ресурсов ОСndash Слабая параллелизация приложения

bull Высокая утилизация ядра ОСndash Частые блокировкиndash Частое обращение к ОС

bull Высокая утилизация CPU ndash Неоптимальная архитектура приложенияndash Неправильное использование APIndash Неоптимизированные горячие методыndash Неоптимальные настройки GC

10 copy JavaTechDays 2011 Oracle Corporation

Solaris Linux Windows Что смотрим

Сеть netstat dtrace netstat perfmon количество соединений объем трафика

Диск iostat dtrace iostat perfmon количество обращений к диску задержка

Память vmstat prstat dtrace

vmstat top perfmon подкачка страниц размер памяти

Процессы ps vmstat mpstat prstat dtrace

ps vmstat top perfmon количество нитей состояние нитей переключения контекста

Ядро ОС mpstat lockstat plockstat dtrace intrstat vmstat

vmstat perfmon kernel time блокировки системные вызовы прерывания

Performance Engineeringинструменты для анализа системы

11 copy JavaTechDays 2011 Oracle Corporation

Performance Engineeringtools tools tools again more tools

bull VisualVM ndash httpvisualvmdevjavanet

bull JRockit Mission Controlndash httpwwworaclecomtechnetworkmiddlewarejrockitmission-controlindexhtml

bull Sun Studio Analyzerndash httpwwworaclecomtechnetworkserver-storagesolarisstudiooverviewindexhtml

bull NetBeans Profilerndash httpwwwnetbeansorg

bull DTracendash httpwwworaclecomtechnetworksystemsdtracedtraceindexhtml

bull Ещё могут быть полезныndash JProbendash OptimizeItndash YourKit

13 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingна чём измерять производительность

ldquoмикроrdquoбенчмарки

синтетические бенчмарки

авто-сценарии реальных приложений

реальные приложения

релевантность плохая средняя хорошая отличная

расходы на разработку и поддержку

низкие средние средние высокие

расходы на запуск

низкие низкие средние высокие

сложность интерпретации результатов

очень сложно

средняя достаточно просто

сложно

14 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingнаша стратегия

bull Сделать реальные приложения быстрееndash Но слишком сложно поддерживать и запускатьndash Поэтому

bull Сфокусироваться на синтетических бенчмарках и авто-сценарияхndash SPECjbb SPECjvm SPECjAppServer SPECjEnterprisendash Glassfish Weblogic NetBeans и тпndash Большие in-house нагрузки

bull Пользоваться микробенчмарками с опаскойndash Иногда от них никуда не детьсяndash Очень легко написать очень легко запуститьndash Очень легко ldquoвыстрелить себе в ногуrdquondash что чуть ли не каждую неделю демонстрируется в профильных

блогах

15 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingитак вы решили написать свой бенчмарк

bull Опасайтесь типичных ошибокbull Дизайн эксперимента

ndash Что хотим измеритьndash Каким способом будем измерять

bull Реализация экспериментаndash Отсутствие прогрева ldquoмёртвый кодrdquo etcndash Многопоточность утилизацияndash Контроль переменных результат воспроизводитсяndash Контроль переменных результат вообще зависит от входов

bull Интерпретация результатовndash Что в итоге измерилиndash Значим ли результат

bull 1000 opssec против 1050 opssec ndash прирост или нет

16 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingближе к делу пример

bull Computer Language Benchmark Gamendash httpshootoutaliothdebianorgndash Самый известный полигон для расстрела невинных ног

bull Тест ldquoPiDigitsrdquondash Вычислить первые N цифр в десятичном разложении πndash Вычисляется приближение π специальным рядом

bull Требуется arbitrary precision для представления рациональных членов ряда

ndash Потенциально параллелизуемаndash Две версии Java-теста

bull Текущая использует GNU MP внутренне параллельна 240 строк кода Java + нативные врапперы + GMP

bull Предыдущая использует BigInteger не параллельна 130 строк кода plain Java

17 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingближе к делу пример

bull Computer Language Benchmark Gamendash httpshootoutaliothdebianorgndash Самый известный полигон для расстрела невинных ног

bull Тест ldquoPiDigitsrdquondash Вычислить первые N цифр в десятичном разложении πndash Вычисляется приближение π специальным рядом

bull Требуется arbitrary precision для представления рациональных членов ряда

ndash Потенциально параллелизуемаndash Две версии Java-теста

bull Текущая использует GNU MP внутренне параллельна 240 строк кода Java + нативные врапперы + GMP

bull Предыдущая использует BigInteger не параллельна 130 строк кода plain Java

18 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingближе к делу пример

bull Метрика время исполненияndash time java -server pidigits 1000

bull ldquoПрогреемrdquo

pidigitsjavasteady public static void main(String[] args) pidigits m = new pidigits(IntegerparseInt(args[0])) for (int i=0 ilt65 ++i) mpidigits(false) mpidigits(true)

19 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingближе к делу пример

bull Метрика время исполненияndash time java -server pidigits 1000

bull ldquoПрогреемrdquo

pidigitsjavasteady public static void main(String[] args) pidigits m = new pidigits(IntegerparseInt(args[0])) for (int i=0 ilt65 ++i) mpidigits(false) mpidigits(true)

20 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingближе к делу пример

bull Метрика время исполненияndash time java -server pidigits 1000

bull ldquoПрогреемrdquo

pidigitsjava public static void main(String[] args) pidigits m = new pidigits(IntegerparseInt(args[0])) for (int i=0 ilt19 ++i) mpidigits(false) mpidigits(true)

pidigitsjavasteady public static void main(String[] args) pidigits m = new pidigits(IntegerparseInt(args[0])) for (int i=0 ilt65 ++i) mpidigits(false) mpidigits(true)

21 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingв век многоядерных систем

bull Обычная платформаndash 2x2 Intel i5 26 Ghz Ubuntu 1010 i686 JDK 6u25

bull Три варианта экспериментаndash 1 экземпляр бенчмарка

bull по ldquoметодологии CLBGrdquo (+ корректный прогрев)

bull GMP будет использовать 1x4=4 потока

bull BI будет использовать 1x1=1 поток

ndash 4 экземпляра бенчмарка

bull чтобы утилизировать все ядра = снормировать на систему

bull GMP будет использовать 4х4=16 потоков

bull BI будет использовать 4x1=4 потока

ndash 16 потоков

bull ради одинаковой нагрузки на OS = снормировать на систему+OS

bull GMP будет использовать 4х4=16 потоков

bull BI будет работать в 16x1=16 потоков

bull Какой из них наиболее релевантен

22 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingа вот и данные

1 экземпляр 4 экземпляра 16 потоков

ldquoGMPrdquo

884[869 899]

1328 [1286 1371]

1328 [1286 1371]

ldquoBigIntegerrdquo

621 [619 624]

1346 [1335 1356]

1434 [1421 1446]

bull Метрика операции в секундуndash 20 итерацийndash [a b] ndash доверительный интервал на 95

24 copy JavaTechDays 2011 Oracle Corporation

Java 7 Java 8что ожидать в области производительности

bull Java 7ndash invokedynamicndash NIO2ndash Concurrency and Collection updates (ForkJoin)ndash XRender pipeline for Java2D (client)

bull Java 8 (или позже)ndash Модульностьndash -выражения (замыкания)ndash Collection updates (filter map reduce)

25 copy JavaTechDays 2011 Oracle Corporation

bull Мешает ли улучшать производительность JVMndash Да поэтому иногда расширяемся

bull invokedynamicbull Модульность

bull Стоит ли расширяться по первому требованию ndash Нет развитие JVMJIT реализация новых методов оптимизации

позволяет получить бОльший выигрышbull Вложенные классыbull Reflection

Обратная совместимость

26 copy JavaTechDays 2011 Oracle Corporation

Solaris

Лучшая ОС для Javaугадайте какая

bull Высокопроизводительный TCPIP стекndash low-latencyndash up to 50 faster

bull DTracendash мониторинг

bull NUMAndash MPO Memory Placement Optimization

bull Large Pagesndash Автоматическая аллокацияndash Разные размеры

27 copy JavaTechDays 2011 Oracle Corporation

hellip and beyondнастройка параметров JVM

bull Что настраиватьndash httpblogssuncomwattresourcejvm-options-listhtml

ndash httpwwworaclecomtechnetworkjavajavasetechvmoptions-jsp-140102html

bull JVM сама подбирает оптимальные параметры своей работыndash Server vs Client ndash Large pages (Solaris)ndash CompressedOops (64-bit VM)

bull Так что же настраиватьndash GCHeap tuningndash -XX+UseNUMA (Solaris Linux)ndash -XX+UseLargePages (Linux Windows)

bull httpwwworaclecomtechnetworkjavajavasetechlargememory-jsp-137182html

bull Не забытьndash Использовать последнюю версию JDK

29 copy JavaTechDays 2011 Oracle Corporation

Concurrencyэлементная база

bull OS Threadingndash мьютексы

bull mutex_lock()mutex_unlock()ndash conditional waits

bull cond_wait()cond_signal()bull WaitForSingleObject

bull Compare-and-Swap (CAS)ndash CAS(x1 x2 x3) = if (x1 == x2) x1 = x3 ndash атомарная операция поддерживаемая в ldquoжелезеrdquo из нескольких

одновременных CASов успешно завершается только одинndash Миф локальный CAS блокирует шину и стоит больше на

многопроцессорных системах ndash Факт глобальный CAS требует трафика на шине

httpblogssuncomdaveentrybiased_locking_in_hotspot

30 copy JavaTechDays 2011 Oracle Corporation

Concurrencyatomics

bull javautilconcurrentAtomicndash обеспечивают атомарные операции над примитивами и указателямиndash альтернатива synchronized или Lockи

bull Трюк в использовании CASаndash Изменение состояния атомика делается при помощи одного CASаndash Чтение состояния не требует CASа

public final int incrementAndGet() for () int current = get() int next = current + 1 if (compareAndSet(current next)) return next

mov ecxedxmov 0x8(ecx)eaxlea 0x8(ecx)edimov eaxecxinc ecxlock cmpxchg ecx(edi)mov $0x0ebxjne [ok]mov $0x1ebxtest ebxebxje [ok]

31 copy JavaTechDays 2011 Oracle Corporation

Concurrencyvolatile

bull Volatile определяет порядок чтения-записей в полеndash Точная семантика определена в Java Memory Model

bull НЕ обеспечивает атомарностиndash Реализуется расстановкой барьеров

bull Какие из них вставятся в код зависит от Hardware Memory Modelbull Эффект барьера зависит от HMM

PUSHL EBPSUB ESP8MOV EBX[ECX + 12]MEMBAR-acquireMEMBAR-releaseINC EBXMOV [ECX + 12]EBXMEMBAR-volatileLOCK ADDL [ESP + 0] 0ADD ESP8POPL EBPTEST PollPageEAXRET

push ebpsub $0x8espmov 0xc(ecx)ebxinc ebxmov ebx0xc(ecx)lock addl $0x0(esp)add $0x8esppop ebptest eax0xb779c000ret

httpgoswegoedudljmmcookbookhtml

32 copy JavaTechDays 2011 Oracle Corporation

Concurrencyvolatile-счётчик

public class VolatileTest

private int counter = 0 private volatile int volatileCounter = 0

GenerateMicroBenchmark public void testOrdinary() counter++

GenerateMicroBenchmark public void testVolatile() volatileCounter++

33 copy JavaTechDays 2011 Oracle Corporation

Concurrencyбесконфликтный volatile-счётчик

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

500000

1000000

1500000

2000000

2500000

3000000

3500000

Thread-local counter performance

ordinary volatile

Threads

op

ss

ec

34 copy JavaTechDays 2011 Oracle Corporation

Concurrencyконфликтный volatile-счётчик

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

100000

200000

300000

400000

500000

600000

700000

800000

900000

Global counter performance

ordinary volatile

Threads

op

ss

ec

35 copy JavaTechDays 2011 Oracle Corporation

Concurrencyintrinsic synchronization

bull synchronized(object) bull 4 состояния

ndash Initbull Начальное ldquoнеопределённоеrdquo состояние

ndash Biasedbull Захватывается одним ldquoвладеющимrdquo потоком нет конфликтовbull Захват владельцем проверка на threadIDbull Захват не-владельцем переход либо в Biased либо в Thin

ndash Thinbull Захватывается несколькими потоками но конфликтов нетbull Захват CASbull Конфликтный захват переход в Fat

ndash Fatbull Захватывается несколькими потоками конфликт на блокировкеbull Вызов примитива синхронизации из ОС

36 copy JavaTechDays 2011 Oracle Corporation

ConcurrencyjavautilconcurrentLock

bull Построены на базе jucAbstractQueueSynchronizerndash Использует атомики

bull CAS

ndash Использует Unsafepark()unpark()

bull интринзики для cond_wait()cond_signal()WaitForSingleObject()

bull ReentrantLockndash По семантике эквивалентен synchronized

bull Рекурсивный захват проверка на threadID

bull Ставит потоки во внутреннюю очередь и делает park()

ndash Non-Fair (default)

bull Не гарантирует отсутствие starvation

bull Barging FIFO (CAS)

bull Лучшая производительность

ndash Fair

bull Гарантирует отсутствие starvation

bull FIFO

bull Честность в обмен на производительностьhttpgeecsoswegoedudlpapersaqspdf

37 copy JavaTechDays 2011 Oracle Corporation

Concurrencyатомарный счётчик

private AtomicInteger atomic = new AtomicInteger() private ReentrantLock lock = new ReentrantLock() private final Object intrinsicLock = new Object() private int primCounter = 0

GenerateMicroBenchmark public void testAtomicInteger() atomicincrementAndGet()

GenerateMicroBenchmark public void testReentrantLock() locklock() primCounter++ lockunlock()

GenerateMicroBenchmark public void testIntrinsicLock() synchronized (intrinsicLock) primCounter++

38 copy JavaTechDays 2011 Oracle Corporation

Concurrencyатомарный счётчик

0 16 32 48 64 80 96 112 128

1000

10000

100000

Atomic Counter Performance

Intrinsic AtomicInteger ReentrantLock

Threads

ops

sec

8x8 CPUs Solaris 6u25

39 copy JavaTechDays 2011 Oracle Corporation

ConcurrencyReentrantLock vs synchronized

bull Семантика одинаковаndash Требования к видимости памяти

ndash Рекурсивный

bull Плюсы jucRLndash Очередь потоков держится на стороне JVM

bull опционально FIFO-политика при захвате-освобождении

bull позволяет быть ldquoчестнымrdquo на любой платформе

ndash Barging FIFO policy

bull lock() может быть сразу удовлетворён даже если в очереди есть потоки

bull сильно улучшает производительность при конфликте блокировок

ndash Допускается несколько Condition

bull Минусы jucRLndash Нет scopeов требуется ручной unlock() через finally

bull Должно быть проще с ARM в JDK7

40 copy JavaTechDays 2011 Oracle Corporation

Concurrencyбесконфликтный захват

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

10000

20000

30000

40000

50000

60000

70000

80000

90000

100000

110000

120000

130000

140000

150000

Uncontended Lock Performance

intrinsic jucReentrantL (non-fair) jucReentrantL (fair)

Threads

op

sse

c

41 copy JavaTechDays 2011 Oracle Corporation

Concurrencyконфликтный захват

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

500

1000

1500

2000

2500

3000

3500

4000

4500

Contended Lock Performance

intrinsic jucReentrantL (non-fair) jucReentrantL (fair)

Threads

op

sse

c

43 copy 2011 JavaTechDays Oracle Corporation

bull hellip естьbull hellip работаетbull hellip работает хорошоbull hellip знает о железе всё

ndash Количество и тип CPUndash Поддерживаемые инcтрукции (SSEx AVX VIS)ndash Топологию памяти (в тч размеры кэшей и их характеристики)

bull hellip знает о приложении много всегоndash Иерархию загруженных классовndash Актуальную статистику создания объектовndash Горячий кодndash Какие ветвления исполнялисьndash Какие значения использовалисьndash Многое другое

bull hellip не боится использовать эти знания для компиляции

JITфакты

44 copy 2011 JavaTechDays Oracle Corporation

JITоптимизации

46 copy 2011 JavaTechDays Oracle Corporation

JITкак писать код

bull Используйте стандартные библиотекиndash Зачем писать собственный стандартный контейнер

bull Используйте высокоуровневый API ndash javautilndash javautilconcurrentndash NIO NIO2ndash вообще библиотеки

bull Код должен правильным и понятнымndash Сначала правильноndash Потом алгоритмически ldquoбыстроrdquondash Код не должен быть JIT-oriented

bull Правильно используйте возможности языкаndash EPIC FAIL штатная передача управления exceptionамиndash FAIL Возврат ldquoисключенияrdquo через return ltкод_ошибкиgtndash FAIL int вместо Enum или boolean

47 copy 2011 JavaTechDays Oracle Corporation

Как получить ассемблерный код метода

ndash Обычным дебаггером )

ndash JVMTI

ndash -XX+PrintAssemblybull httpwikissuncomdisplayHotSpotInternalsPrintAssembly

JITдля любопытных

54 copy JavaTechDays 2011 Oracle Corporation

StartupEclipse

bull Типичная конфигурацияndash 2x2 Intel i5 26 Ghz Ubuntu 1010 i686 JDK 6u25ndash Eclipse JDT (Galileo)

bull Типичные метрикиndash 6000 загруженных классовndash 1000 методов скомпилированоndash 512 Mb зарезервированного пространства в кучеndash 25 Mb кучи использовано после стартапа

bull Известные ldquoпроблемыrdquondash Загрузка и верификация классовndash JIT-компиляция

55 copy JavaTechDays 2011 Oracle Corporation

StartupEclipse

bull Метрика секунд на запуск-завершениеndash Файловые кеши прогреты практически нулевой дисковый IO

default CDS CDS + no-verify

абсолютное время

583 [574 592]

481[473 484]

461[456 474]

загрузка классов

501[491 511]

339[312 366]

301[294 308]

компиляция 051[043 059]

051[044 058]

051[042 060]

56 copy JavaTechDays 2011 Oracle Corporation

Startupдлинные приложения

bull Важно только для коротких приложенийndash Чем дольше работает приложение тем меньше удельные затраты на

загрузку классов и компиляцию

bull Пример 8 часа работает IntelliJ IDEA 10xndash 26600 классов загруженоndash 5315 методов скомпилировано

bull Загрузка классовndash Всего потрачено 202 с ~07 общего времениndash 10 мсек на класс

bull Компиляцияndash Всего потрачено 112 с ~003 общего времениndash 20 мсек на метод

57 copy JavaTechDays 2011 Oracle Corporation

Whats Next

bull Послушать ещёndash JavaOne Moscow (апрель 2011)

bull Проблема со слайдамиndash Найдите нас на конференцииndash Напишите нам письмо

bull Проблема с JDKndash httpopenjdkjavanetndash Задайте вопрос в OpenJDKndash а лучше сделайте патч и дайте его в OpenJDK на review

58 copy JavaTechDays 2011 Oracle Corporation

QA

Page 2: Java Platform Performance BoF - Aleksey Shipilëv · – 2x2 Intel i5 2.6 Ghz, Ubuntu 10.10 i686, JDK 6u25 • Три варианта эксперимента: – 1 экземпляр

4 copy JavaTechDays 2011 Oracle Corporation

Performance Engineeringабстрактно и отлично об отличиях в абстракциях

bull Computer Science rarr Software Engineeringndash Строим приложения по функциональным требованиямndash В большой степени абстрактно в ldquoидеальном миреrdquo

bull Теоретически неограниченная свобода ndash искусствоbull Можно строить воздушные зАмки

ndash Рассуждения при помощи формальных методов

bull Software Performance Engineeringndash ldquoReal world strikes backrdquo

bull Алгоритмическая сложность всей системы целикомbull Физические ограничения на скорость выполнения

ndash Исследуем взаимодействие софта с железом на типичных данныхndash Естественно-научные методы

bull Основываемся на эмпирических данных

5 copy JavaTechDays 2011 Oracle Corporation

Performance Engineeringпервый шаг

bull Классические ошибки первого шагаndash ldquoя вижу что метод foo() реализован неэффективноrdquondash ldquoпо профилю видно что метод bar() ndash самый горячий и занимает 5rdquo

ndash ldquoпо-моему у нас тормозит БД и необходимо перейти с DBX на DB

Yrdquo

bull Правильный первый шагndash Необходимо выбрать метрику

bull opssec transactionssecbull время исполненияbull время отклика

ndash Убедиться в корректности метрикиbull релевантна (учитывает реальный сценарий работы приложения)bull повторяема

ЦЕЛЬ rarr улучшение метрики

7 copy JavaTechDays 2011 Oracle Corporation

Performance Engineeringанализ узких мест

bull Что ограничивает скорость работы приложения

bull CPUbull Ядро ОСbull IO (Сеть Диск)

9 copy JavaTechDays 2011 Oracle Corporation

Performance Engineeringанализ узких мест (tips)

bull Низкая утилизация CPUndash Высокая дисковая сетевая активностьndash Конфликт блокировокndash Конфликт ресурсов ОСndash Слабая параллелизация приложения

bull Высокая утилизация ядра ОСndash Частые блокировкиndash Частое обращение к ОС

bull Высокая утилизация CPU ndash Неоптимальная архитектура приложенияndash Неправильное использование APIndash Неоптимизированные горячие методыndash Неоптимальные настройки GC

10 copy JavaTechDays 2011 Oracle Corporation

Solaris Linux Windows Что смотрим

Сеть netstat dtrace netstat perfmon количество соединений объем трафика

Диск iostat dtrace iostat perfmon количество обращений к диску задержка

Память vmstat prstat dtrace

vmstat top perfmon подкачка страниц размер памяти

Процессы ps vmstat mpstat prstat dtrace

ps vmstat top perfmon количество нитей состояние нитей переключения контекста

Ядро ОС mpstat lockstat plockstat dtrace intrstat vmstat

vmstat perfmon kernel time блокировки системные вызовы прерывания

Performance Engineeringинструменты для анализа системы

11 copy JavaTechDays 2011 Oracle Corporation

Performance Engineeringtools tools tools again more tools

bull VisualVM ndash httpvisualvmdevjavanet

bull JRockit Mission Controlndash httpwwworaclecomtechnetworkmiddlewarejrockitmission-controlindexhtml

bull Sun Studio Analyzerndash httpwwworaclecomtechnetworkserver-storagesolarisstudiooverviewindexhtml

bull NetBeans Profilerndash httpwwwnetbeansorg

bull DTracendash httpwwworaclecomtechnetworksystemsdtracedtraceindexhtml

bull Ещё могут быть полезныndash JProbendash OptimizeItndash YourKit

13 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingна чём измерять производительность

ldquoмикроrdquoбенчмарки

синтетические бенчмарки

авто-сценарии реальных приложений

реальные приложения

релевантность плохая средняя хорошая отличная

расходы на разработку и поддержку

низкие средние средние высокие

расходы на запуск

низкие низкие средние высокие

сложность интерпретации результатов

очень сложно

средняя достаточно просто

сложно

14 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingнаша стратегия

bull Сделать реальные приложения быстрееndash Но слишком сложно поддерживать и запускатьndash Поэтому

bull Сфокусироваться на синтетических бенчмарках и авто-сценарияхndash SPECjbb SPECjvm SPECjAppServer SPECjEnterprisendash Glassfish Weblogic NetBeans и тпndash Большие in-house нагрузки

bull Пользоваться микробенчмарками с опаскойndash Иногда от них никуда не детьсяndash Очень легко написать очень легко запуститьndash Очень легко ldquoвыстрелить себе в ногуrdquondash что чуть ли не каждую неделю демонстрируется в профильных

блогах

15 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingитак вы решили написать свой бенчмарк

bull Опасайтесь типичных ошибокbull Дизайн эксперимента

ndash Что хотим измеритьndash Каким способом будем измерять

bull Реализация экспериментаndash Отсутствие прогрева ldquoмёртвый кодrdquo etcndash Многопоточность утилизацияndash Контроль переменных результат воспроизводитсяndash Контроль переменных результат вообще зависит от входов

bull Интерпретация результатовndash Что в итоге измерилиndash Значим ли результат

bull 1000 opssec против 1050 opssec ndash прирост или нет

16 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingближе к делу пример

bull Computer Language Benchmark Gamendash httpshootoutaliothdebianorgndash Самый известный полигон для расстрела невинных ног

bull Тест ldquoPiDigitsrdquondash Вычислить первые N цифр в десятичном разложении πndash Вычисляется приближение π специальным рядом

bull Требуется arbitrary precision для представления рациональных членов ряда

ndash Потенциально параллелизуемаndash Две версии Java-теста

bull Текущая использует GNU MP внутренне параллельна 240 строк кода Java + нативные врапперы + GMP

bull Предыдущая использует BigInteger не параллельна 130 строк кода plain Java

17 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingближе к делу пример

bull Computer Language Benchmark Gamendash httpshootoutaliothdebianorgndash Самый известный полигон для расстрела невинных ног

bull Тест ldquoPiDigitsrdquondash Вычислить первые N цифр в десятичном разложении πndash Вычисляется приближение π специальным рядом

bull Требуется arbitrary precision для представления рациональных членов ряда

ndash Потенциально параллелизуемаndash Две версии Java-теста

bull Текущая использует GNU MP внутренне параллельна 240 строк кода Java + нативные врапперы + GMP

bull Предыдущая использует BigInteger не параллельна 130 строк кода plain Java

18 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingближе к делу пример

bull Метрика время исполненияndash time java -server pidigits 1000

bull ldquoПрогреемrdquo

pidigitsjavasteady public static void main(String[] args) pidigits m = new pidigits(IntegerparseInt(args[0])) for (int i=0 ilt65 ++i) mpidigits(false) mpidigits(true)

19 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingближе к делу пример

bull Метрика время исполненияndash time java -server pidigits 1000

bull ldquoПрогреемrdquo

pidigitsjavasteady public static void main(String[] args) pidigits m = new pidigits(IntegerparseInt(args[0])) for (int i=0 ilt65 ++i) mpidigits(false) mpidigits(true)

20 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingближе к делу пример

bull Метрика время исполненияndash time java -server pidigits 1000

bull ldquoПрогреемrdquo

pidigitsjava public static void main(String[] args) pidigits m = new pidigits(IntegerparseInt(args[0])) for (int i=0 ilt19 ++i) mpidigits(false) mpidigits(true)

pidigitsjavasteady public static void main(String[] args) pidigits m = new pidigits(IntegerparseInt(args[0])) for (int i=0 ilt65 ++i) mpidigits(false) mpidigits(true)

21 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingв век многоядерных систем

bull Обычная платформаndash 2x2 Intel i5 26 Ghz Ubuntu 1010 i686 JDK 6u25

bull Три варианта экспериментаndash 1 экземпляр бенчмарка

bull по ldquoметодологии CLBGrdquo (+ корректный прогрев)

bull GMP будет использовать 1x4=4 потока

bull BI будет использовать 1x1=1 поток

ndash 4 экземпляра бенчмарка

bull чтобы утилизировать все ядра = снормировать на систему

bull GMP будет использовать 4х4=16 потоков

bull BI будет использовать 4x1=4 потока

ndash 16 потоков

bull ради одинаковой нагрузки на OS = снормировать на систему+OS

bull GMP будет использовать 4х4=16 потоков

bull BI будет работать в 16x1=16 потоков

bull Какой из них наиболее релевантен

22 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingа вот и данные

1 экземпляр 4 экземпляра 16 потоков

ldquoGMPrdquo

884[869 899]

1328 [1286 1371]

1328 [1286 1371]

ldquoBigIntegerrdquo

621 [619 624]

1346 [1335 1356]

1434 [1421 1446]

bull Метрика операции в секундуndash 20 итерацийndash [a b] ndash доверительный интервал на 95

24 copy JavaTechDays 2011 Oracle Corporation

Java 7 Java 8что ожидать в области производительности

bull Java 7ndash invokedynamicndash NIO2ndash Concurrency and Collection updates (ForkJoin)ndash XRender pipeline for Java2D (client)

bull Java 8 (или позже)ndash Модульностьndash -выражения (замыкания)ndash Collection updates (filter map reduce)

25 copy JavaTechDays 2011 Oracle Corporation

bull Мешает ли улучшать производительность JVMndash Да поэтому иногда расширяемся

bull invokedynamicbull Модульность

bull Стоит ли расширяться по первому требованию ndash Нет развитие JVMJIT реализация новых методов оптимизации

позволяет получить бОльший выигрышbull Вложенные классыbull Reflection

Обратная совместимость

26 copy JavaTechDays 2011 Oracle Corporation

Solaris

Лучшая ОС для Javaугадайте какая

bull Высокопроизводительный TCPIP стекndash low-latencyndash up to 50 faster

bull DTracendash мониторинг

bull NUMAndash MPO Memory Placement Optimization

bull Large Pagesndash Автоматическая аллокацияndash Разные размеры

27 copy JavaTechDays 2011 Oracle Corporation

hellip and beyondнастройка параметров JVM

bull Что настраиватьndash httpblogssuncomwattresourcejvm-options-listhtml

ndash httpwwworaclecomtechnetworkjavajavasetechvmoptions-jsp-140102html

bull JVM сама подбирает оптимальные параметры своей работыndash Server vs Client ndash Large pages (Solaris)ndash CompressedOops (64-bit VM)

bull Так что же настраиватьndash GCHeap tuningndash -XX+UseNUMA (Solaris Linux)ndash -XX+UseLargePages (Linux Windows)

bull httpwwworaclecomtechnetworkjavajavasetechlargememory-jsp-137182html

bull Не забытьndash Использовать последнюю версию JDK

29 copy JavaTechDays 2011 Oracle Corporation

Concurrencyэлементная база

bull OS Threadingndash мьютексы

bull mutex_lock()mutex_unlock()ndash conditional waits

bull cond_wait()cond_signal()bull WaitForSingleObject

bull Compare-and-Swap (CAS)ndash CAS(x1 x2 x3) = if (x1 == x2) x1 = x3 ndash атомарная операция поддерживаемая в ldquoжелезеrdquo из нескольких

одновременных CASов успешно завершается только одинndash Миф локальный CAS блокирует шину и стоит больше на

многопроцессорных системах ndash Факт глобальный CAS требует трафика на шине

httpblogssuncomdaveentrybiased_locking_in_hotspot

30 copy JavaTechDays 2011 Oracle Corporation

Concurrencyatomics

bull javautilconcurrentAtomicndash обеспечивают атомарные операции над примитивами и указателямиndash альтернатива synchronized или Lockи

bull Трюк в использовании CASаndash Изменение состояния атомика делается при помощи одного CASаndash Чтение состояния не требует CASа

public final int incrementAndGet() for () int current = get() int next = current + 1 if (compareAndSet(current next)) return next

mov ecxedxmov 0x8(ecx)eaxlea 0x8(ecx)edimov eaxecxinc ecxlock cmpxchg ecx(edi)mov $0x0ebxjne [ok]mov $0x1ebxtest ebxebxje [ok]

31 copy JavaTechDays 2011 Oracle Corporation

Concurrencyvolatile

bull Volatile определяет порядок чтения-записей в полеndash Точная семантика определена в Java Memory Model

bull НЕ обеспечивает атомарностиndash Реализуется расстановкой барьеров

bull Какие из них вставятся в код зависит от Hardware Memory Modelbull Эффект барьера зависит от HMM

PUSHL EBPSUB ESP8MOV EBX[ECX + 12]MEMBAR-acquireMEMBAR-releaseINC EBXMOV [ECX + 12]EBXMEMBAR-volatileLOCK ADDL [ESP + 0] 0ADD ESP8POPL EBPTEST PollPageEAXRET

push ebpsub $0x8espmov 0xc(ecx)ebxinc ebxmov ebx0xc(ecx)lock addl $0x0(esp)add $0x8esppop ebptest eax0xb779c000ret

httpgoswegoedudljmmcookbookhtml

32 copy JavaTechDays 2011 Oracle Corporation

Concurrencyvolatile-счётчик

public class VolatileTest

private int counter = 0 private volatile int volatileCounter = 0

GenerateMicroBenchmark public void testOrdinary() counter++

GenerateMicroBenchmark public void testVolatile() volatileCounter++

33 copy JavaTechDays 2011 Oracle Corporation

Concurrencyбесконфликтный volatile-счётчик

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

500000

1000000

1500000

2000000

2500000

3000000

3500000

Thread-local counter performance

ordinary volatile

Threads

op

ss

ec

34 copy JavaTechDays 2011 Oracle Corporation

Concurrencyконфликтный volatile-счётчик

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

100000

200000

300000

400000

500000

600000

700000

800000

900000

Global counter performance

ordinary volatile

Threads

op

ss

ec

35 copy JavaTechDays 2011 Oracle Corporation

Concurrencyintrinsic synchronization

bull synchronized(object) bull 4 состояния

ndash Initbull Начальное ldquoнеопределённоеrdquo состояние

ndash Biasedbull Захватывается одним ldquoвладеющимrdquo потоком нет конфликтовbull Захват владельцем проверка на threadIDbull Захват не-владельцем переход либо в Biased либо в Thin

ndash Thinbull Захватывается несколькими потоками но конфликтов нетbull Захват CASbull Конфликтный захват переход в Fat

ndash Fatbull Захватывается несколькими потоками конфликт на блокировкеbull Вызов примитива синхронизации из ОС

36 copy JavaTechDays 2011 Oracle Corporation

ConcurrencyjavautilconcurrentLock

bull Построены на базе jucAbstractQueueSynchronizerndash Использует атомики

bull CAS

ndash Использует Unsafepark()unpark()

bull интринзики для cond_wait()cond_signal()WaitForSingleObject()

bull ReentrantLockndash По семантике эквивалентен synchronized

bull Рекурсивный захват проверка на threadID

bull Ставит потоки во внутреннюю очередь и делает park()

ndash Non-Fair (default)

bull Не гарантирует отсутствие starvation

bull Barging FIFO (CAS)

bull Лучшая производительность

ndash Fair

bull Гарантирует отсутствие starvation

bull FIFO

bull Честность в обмен на производительностьhttpgeecsoswegoedudlpapersaqspdf

37 copy JavaTechDays 2011 Oracle Corporation

Concurrencyатомарный счётчик

private AtomicInteger atomic = new AtomicInteger() private ReentrantLock lock = new ReentrantLock() private final Object intrinsicLock = new Object() private int primCounter = 0

GenerateMicroBenchmark public void testAtomicInteger() atomicincrementAndGet()

GenerateMicroBenchmark public void testReentrantLock() locklock() primCounter++ lockunlock()

GenerateMicroBenchmark public void testIntrinsicLock() synchronized (intrinsicLock) primCounter++

38 copy JavaTechDays 2011 Oracle Corporation

Concurrencyатомарный счётчик

0 16 32 48 64 80 96 112 128

1000

10000

100000

Atomic Counter Performance

Intrinsic AtomicInteger ReentrantLock

Threads

ops

sec

8x8 CPUs Solaris 6u25

39 copy JavaTechDays 2011 Oracle Corporation

ConcurrencyReentrantLock vs synchronized

bull Семантика одинаковаndash Требования к видимости памяти

ndash Рекурсивный

bull Плюсы jucRLndash Очередь потоков держится на стороне JVM

bull опционально FIFO-политика при захвате-освобождении

bull позволяет быть ldquoчестнымrdquo на любой платформе

ndash Barging FIFO policy

bull lock() может быть сразу удовлетворён даже если в очереди есть потоки

bull сильно улучшает производительность при конфликте блокировок

ndash Допускается несколько Condition

bull Минусы jucRLndash Нет scopeов требуется ручной unlock() через finally

bull Должно быть проще с ARM в JDK7

40 copy JavaTechDays 2011 Oracle Corporation

Concurrencyбесконфликтный захват

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

10000

20000

30000

40000

50000

60000

70000

80000

90000

100000

110000

120000

130000

140000

150000

Uncontended Lock Performance

intrinsic jucReentrantL (non-fair) jucReentrantL (fair)

Threads

op

sse

c

41 copy JavaTechDays 2011 Oracle Corporation

Concurrencyконфликтный захват

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

500

1000

1500

2000

2500

3000

3500

4000

4500

Contended Lock Performance

intrinsic jucReentrantL (non-fair) jucReentrantL (fair)

Threads

op

sse

c

43 copy 2011 JavaTechDays Oracle Corporation

bull hellip естьbull hellip работаетbull hellip работает хорошоbull hellip знает о железе всё

ndash Количество и тип CPUndash Поддерживаемые инcтрукции (SSEx AVX VIS)ndash Топологию памяти (в тч размеры кэшей и их характеристики)

bull hellip знает о приложении много всегоndash Иерархию загруженных классовndash Актуальную статистику создания объектовndash Горячий кодndash Какие ветвления исполнялисьndash Какие значения использовалисьndash Многое другое

bull hellip не боится использовать эти знания для компиляции

JITфакты

44 copy 2011 JavaTechDays Oracle Corporation

JITоптимизации

46 copy 2011 JavaTechDays Oracle Corporation

JITкак писать код

bull Используйте стандартные библиотекиndash Зачем писать собственный стандартный контейнер

bull Используйте высокоуровневый API ndash javautilndash javautilconcurrentndash NIO NIO2ndash вообще библиотеки

bull Код должен правильным и понятнымndash Сначала правильноndash Потом алгоритмически ldquoбыстроrdquondash Код не должен быть JIT-oriented

bull Правильно используйте возможности языкаndash EPIC FAIL штатная передача управления exceptionамиndash FAIL Возврат ldquoисключенияrdquo через return ltкод_ошибкиgtndash FAIL int вместо Enum или boolean

47 copy 2011 JavaTechDays Oracle Corporation

Как получить ассемблерный код метода

ndash Обычным дебаггером )

ndash JVMTI

ndash -XX+PrintAssemblybull httpwikissuncomdisplayHotSpotInternalsPrintAssembly

JITдля любопытных

54 copy JavaTechDays 2011 Oracle Corporation

StartupEclipse

bull Типичная конфигурацияndash 2x2 Intel i5 26 Ghz Ubuntu 1010 i686 JDK 6u25ndash Eclipse JDT (Galileo)

bull Типичные метрикиndash 6000 загруженных классовndash 1000 методов скомпилированоndash 512 Mb зарезервированного пространства в кучеndash 25 Mb кучи использовано после стартапа

bull Известные ldquoпроблемыrdquondash Загрузка и верификация классовndash JIT-компиляция

55 copy JavaTechDays 2011 Oracle Corporation

StartupEclipse

bull Метрика секунд на запуск-завершениеndash Файловые кеши прогреты практически нулевой дисковый IO

default CDS CDS + no-verify

абсолютное время

583 [574 592]

481[473 484]

461[456 474]

загрузка классов

501[491 511]

339[312 366]

301[294 308]

компиляция 051[043 059]

051[044 058]

051[042 060]

56 copy JavaTechDays 2011 Oracle Corporation

Startupдлинные приложения

bull Важно только для коротких приложенийndash Чем дольше работает приложение тем меньше удельные затраты на

загрузку классов и компиляцию

bull Пример 8 часа работает IntelliJ IDEA 10xndash 26600 классов загруженоndash 5315 методов скомпилировано

bull Загрузка классовndash Всего потрачено 202 с ~07 общего времениndash 10 мсек на класс

bull Компиляцияndash Всего потрачено 112 с ~003 общего времениndash 20 мсек на метод

57 copy JavaTechDays 2011 Oracle Corporation

Whats Next

bull Послушать ещёndash JavaOne Moscow (апрель 2011)

bull Проблема со слайдамиndash Найдите нас на конференцииndash Напишите нам письмо

bull Проблема с JDKndash httpopenjdkjavanetndash Задайте вопрос в OpenJDKndash а лучше сделайте патч и дайте его в OpenJDK на review

58 copy JavaTechDays 2011 Oracle Corporation

QA

Page 3: Java Platform Performance BoF - Aleksey Shipilëv · – 2x2 Intel i5 2.6 Ghz, Ubuntu 10.10 i686, JDK 6u25 • Три варианта эксперимента: – 1 экземпляр

5 copy JavaTechDays 2011 Oracle Corporation

Performance Engineeringпервый шаг

bull Классические ошибки первого шагаndash ldquoя вижу что метод foo() реализован неэффективноrdquondash ldquoпо профилю видно что метод bar() ndash самый горячий и занимает 5rdquo

ndash ldquoпо-моему у нас тормозит БД и необходимо перейти с DBX на DB

Yrdquo

bull Правильный первый шагndash Необходимо выбрать метрику

bull opssec transactionssecbull время исполненияbull время отклика

ndash Убедиться в корректности метрикиbull релевантна (учитывает реальный сценарий работы приложения)bull повторяема

ЦЕЛЬ rarr улучшение метрики

7 copy JavaTechDays 2011 Oracle Corporation

Performance Engineeringанализ узких мест

bull Что ограничивает скорость работы приложения

bull CPUbull Ядро ОСbull IO (Сеть Диск)

9 copy JavaTechDays 2011 Oracle Corporation

Performance Engineeringанализ узких мест (tips)

bull Низкая утилизация CPUndash Высокая дисковая сетевая активностьndash Конфликт блокировокndash Конфликт ресурсов ОСndash Слабая параллелизация приложения

bull Высокая утилизация ядра ОСndash Частые блокировкиndash Частое обращение к ОС

bull Высокая утилизация CPU ndash Неоптимальная архитектура приложенияndash Неправильное использование APIndash Неоптимизированные горячие методыndash Неоптимальные настройки GC

10 copy JavaTechDays 2011 Oracle Corporation

Solaris Linux Windows Что смотрим

Сеть netstat dtrace netstat perfmon количество соединений объем трафика

Диск iostat dtrace iostat perfmon количество обращений к диску задержка

Память vmstat prstat dtrace

vmstat top perfmon подкачка страниц размер памяти

Процессы ps vmstat mpstat prstat dtrace

ps vmstat top perfmon количество нитей состояние нитей переключения контекста

Ядро ОС mpstat lockstat plockstat dtrace intrstat vmstat

vmstat perfmon kernel time блокировки системные вызовы прерывания

Performance Engineeringинструменты для анализа системы

11 copy JavaTechDays 2011 Oracle Corporation

Performance Engineeringtools tools tools again more tools

bull VisualVM ndash httpvisualvmdevjavanet

bull JRockit Mission Controlndash httpwwworaclecomtechnetworkmiddlewarejrockitmission-controlindexhtml

bull Sun Studio Analyzerndash httpwwworaclecomtechnetworkserver-storagesolarisstudiooverviewindexhtml

bull NetBeans Profilerndash httpwwwnetbeansorg

bull DTracendash httpwwworaclecomtechnetworksystemsdtracedtraceindexhtml

bull Ещё могут быть полезныndash JProbendash OptimizeItndash YourKit

13 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingна чём измерять производительность

ldquoмикроrdquoбенчмарки

синтетические бенчмарки

авто-сценарии реальных приложений

реальные приложения

релевантность плохая средняя хорошая отличная

расходы на разработку и поддержку

низкие средние средние высокие

расходы на запуск

низкие низкие средние высокие

сложность интерпретации результатов

очень сложно

средняя достаточно просто

сложно

14 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingнаша стратегия

bull Сделать реальные приложения быстрееndash Но слишком сложно поддерживать и запускатьndash Поэтому

bull Сфокусироваться на синтетических бенчмарках и авто-сценарияхndash SPECjbb SPECjvm SPECjAppServer SPECjEnterprisendash Glassfish Weblogic NetBeans и тпndash Большие in-house нагрузки

bull Пользоваться микробенчмарками с опаскойndash Иногда от них никуда не детьсяndash Очень легко написать очень легко запуститьndash Очень легко ldquoвыстрелить себе в ногуrdquondash что чуть ли не каждую неделю демонстрируется в профильных

блогах

15 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingитак вы решили написать свой бенчмарк

bull Опасайтесь типичных ошибокbull Дизайн эксперимента

ndash Что хотим измеритьndash Каким способом будем измерять

bull Реализация экспериментаndash Отсутствие прогрева ldquoмёртвый кодrdquo etcndash Многопоточность утилизацияndash Контроль переменных результат воспроизводитсяndash Контроль переменных результат вообще зависит от входов

bull Интерпретация результатовndash Что в итоге измерилиndash Значим ли результат

bull 1000 opssec против 1050 opssec ndash прирост или нет

16 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingближе к делу пример

bull Computer Language Benchmark Gamendash httpshootoutaliothdebianorgndash Самый известный полигон для расстрела невинных ног

bull Тест ldquoPiDigitsrdquondash Вычислить первые N цифр в десятичном разложении πndash Вычисляется приближение π специальным рядом

bull Требуется arbitrary precision для представления рациональных членов ряда

ndash Потенциально параллелизуемаndash Две версии Java-теста

bull Текущая использует GNU MP внутренне параллельна 240 строк кода Java + нативные врапперы + GMP

bull Предыдущая использует BigInteger не параллельна 130 строк кода plain Java

17 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingближе к делу пример

bull Computer Language Benchmark Gamendash httpshootoutaliothdebianorgndash Самый известный полигон для расстрела невинных ног

bull Тест ldquoPiDigitsrdquondash Вычислить первые N цифр в десятичном разложении πndash Вычисляется приближение π специальным рядом

bull Требуется arbitrary precision для представления рациональных членов ряда

ndash Потенциально параллелизуемаndash Две версии Java-теста

bull Текущая использует GNU MP внутренне параллельна 240 строк кода Java + нативные врапперы + GMP

bull Предыдущая использует BigInteger не параллельна 130 строк кода plain Java

18 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingближе к делу пример

bull Метрика время исполненияndash time java -server pidigits 1000

bull ldquoПрогреемrdquo

pidigitsjavasteady public static void main(String[] args) pidigits m = new pidigits(IntegerparseInt(args[0])) for (int i=0 ilt65 ++i) mpidigits(false) mpidigits(true)

19 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingближе к делу пример

bull Метрика время исполненияndash time java -server pidigits 1000

bull ldquoПрогреемrdquo

pidigitsjavasteady public static void main(String[] args) pidigits m = new pidigits(IntegerparseInt(args[0])) for (int i=0 ilt65 ++i) mpidigits(false) mpidigits(true)

20 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingближе к делу пример

bull Метрика время исполненияndash time java -server pidigits 1000

bull ldquoПрогреемrdquo

pidigitsjava public static void main(String[] args) pidigits m = new pidigits(IntegerparseInt(args[0])) for (int i=0 ilt19 ++i) mpidigits(false) mpidigits(true)

pidigitsjavasteady public static void main(String[] args) pidigits m = new pidigits(IntegerparseInt(args[0])) for (int i=0 ilt65 ++i) mpidigits(false) mpidigits(true)

21 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingв век многоядерных систем

bull Обычная платформаndash 2x2 Intel i5 26 Ghz Ubuntu 1010 i686 JDK 6u25

bull Три варианта экспериментаndash 1 экземпляр бенчмарка

bull по ldquoметодологии CLBGrdquo (+ корректный прогрев)

bull GMP будет использовать 1x4=4 потока

bull BI будет использовать 1x1=1 поток

ndash 4 экземпляра бенчмарка

bull чтобы утилизировать все ядра = снормировать на систему

bull GMP будет использовать 4х4=16 потоков

bull BI будет использовать 4x1=4 потока

ndash 16 потоков

bull ради одинаковой нагрузки на OS = снормировать на систему+OS

bull GMP будет использовать 4х4=16 потоков

bull BI будет работать в 16x1=16 потоков

bull Какой из них наиболее релевантен

22 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingа вот и данные

1 экземпляр 4 экземпляра 16 потоков

ldquoGMPrdquo

884[869 899]

1328 [1286 1371]

1328 [1286 1371]

ldquoBigIntegerrdquo

621 [619 624]

1346 [1335 1356]

1434 [1421 1446]

bull Метрика операции в секундуndash 20 итерацийndash [a b] ndash доверительный интервал на 95

24 copy JavaTechDays 2011 Oracle Corporation

Java 7 Java 8что ожидать в области производительности

bull Java 7ndash invokedynamicndash NIO2ndash Concurrency and Collection updates (ForkJoin)ndash XRender pipeline for Java2D (client)

bull Java 8 (или позже)ndash Модульностьndash -выражения (замыкания)ndash Collection updates (filter map reduce)

25 copy JavaTechDays 2011 Oracle Corporation

bull Мешает ли улучшать производительность JVMndash Да поэтому иногда расширяемся

bull invokedynamicbull Модульность

bull Стоит ли расширяться по первому требованию ndash Нет развитие JVMJIT реализация новых методов оптимизации

позволяет получить бОльший выигрышbull Вложенные классыbull Reflection

Обратная совместимость

26 copy JavaTechDays 2011 Oracle Corporation

Solaris

Лучшая ОС для Javaугадайте какая

bull Высокопроизводительный TCPIP стекndash low-latencyndash up to 50 faster

bull DTracendash мониторинг

bull NUMAndash MPO Memory Placement Optimization

bull Large Pagesndash Автоматическая аллокацияndash Разные размеры

27 copy JavaTechDays 2011 Oracle Corporation

hellip and beyondнастройка параметров JVM

bull Что настраиватьndash httpblogssuncomwattresourcejvm-options-listhtml

ndash httpwwworaclecomtechnetworkjavajavasetechvmoptions-jsp-140102html

bull JVM сама подбирает оптимальные параметры своей работыndash Server vs Client ndash Large pages (Solaris)ndash CompressedOops (64-bit VM)

bull Так что же настраиватьndash GCHeap tuningndash -XX+UseNUMA (Solaris Linux)ndash -XX+UseLargePages (Linux Windows)

bull httpwwworaclecomtechnetworkjavajavasetechlargememory-jsp-137182html

bull Не забытьndash Использовать последнюю версию JDK

29 copy JavaTechDays 2011 Oracle Corporation

Concurrencyэлементная база

bull OS Threadingndash мьютексы

bull mutex_lock()mutex_unlock()ndash conditional waits

bull cond_wait()cond_signal()bull WaitForSingleObject

bull Compare-and-Swap (CAS)ndash CAS(x1 x2 x3) = if (x1 == x2) x1 = x3 ndash атомарная операция поддерживаемая в ldquoжелезеrdquo из нескольких

одновременных CASов успешно завершается только одинndash Миф локальный CAS блокирует шину и стоит больше на

многопроцессорных системах ndash Факт глобальный CAS требует трафика на шине

httpblogssuncomdaveentrybiased_locking_in_hotspot

30 copy JavaTechDays 2011 Oracle Corporation

Concurrencyatomics

bull javautilconcurrentAtomicndash обеспечивают атомарные операции над примитивами и указателямиndash альтернатива synchronized или Lockи

bull Трюк в использовании CASаndash Изменение состояния атомика делается при помощи одного CASаndash Чтение состояния не требует CASа

public final int incrementAndGet() for () int current = get() int next = current + 1 if (compareAndSet(current next)) return next

mov ecxedxmov 0x8(ecx)eaxlea 0x8(ecx)edimov eaxecxinc ecxlock cmpxchg ecx(edi)mov $0x0ebxjne [ok]mov $0x1ebxtest ebxebxje [ok]

31 copy JavaTechDays 2011 Oracle Corporation

Concurrencyvolatile

bull Volatile определяет порядок чтения-записей в полеndash Точная семантика определена в Java Memory Model

bull НЕ обеспечивает атомарностиndash Реализуется расстановкой барьеров

bull Какие из них вставятся в код зависит от Hardware Memory Modelbull Эффект барьера зависит от HMM

PUSHL EBPSUB ESP8MOV EBX[ECX + 12]MEMBAR-acquireMEMBAR-releaseINC EBXMOV [ECX + 12]EBXMEMBAR-volatileLOCK ADDL [ESP + 0] 0ADD ESP8POPL EBPTEST PollPageEAXRET

push ebpsub $0x8espmov 0xc(ecx)ebxinc ebxmov ebx0xc(ecx)lock addl $0x0(esp)add $0x8esppop ebptest eax0xb779c000ret

httpgoswegoedudljmmcookbookhtml

32 copy JavaTechDays 2011 Oracle Corporation

Concurrencyvolatile-счётчик

public class VolatileTest

private int counter = 0 private volatile int volatileCounter = 0

GenerateMicroBenchmark public void testOrdinary() counter++

GenerateMicroBenchmark public void testVolatile() volatileCounter++

33 copy JavaTechDays 2011 Oracle Corporation

Concurrencyбесконфликтный volatile-счётчик

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

500000

1000000

1500000

2000000

2500000

3000000

3500000

Thread-local counter performance

ordinary volatile

Threads

op

ss

ec

34 copy JavaTechDays 2011 Oracle Corporation

Concurrencyконфликтный volatile-счётчик

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

100000

200000

300000

400000

500000

600000

700000

800000

900000

Global counter performance

ordinary volatile

Threads

op

ss

ec

35 copy JavaTechDays 2011 Oracle Corporation

Concurrencyintrinsic synchronization

bull synchronized(object) bull 4 состояния

ndash Initbull Начальное ldquoнеопределённоеrdquo состояние

ndash Biasedbull Захватывается одним ldquoвладеющимrdquo потоком нет конфликтовbull Захват владельцем проверка на threadIDbull Захват не-владельцем переход либо в Biased либо в Thin

ndash Thinbull Захватывается несколькими потоками но конфликтов нетbull Захват CASbull Конфликтный захват переход в Fat

ndash Fatbull Захватывается несколькими потоками конфликт на блокировкеbull Вызов примитива синхронизации из ОС

36 copy JavaTechDays 2011 Oracle Corporation

ConcurrencyjavautilconcurrentLock

bull Построены на базе jucAbstractQueueSynchronizerndash Использует атомики

bull CAS

ndash Использует Unsafepark()unpark()

bull интринзики для cond_wait()cond_signal()WaitForSingleObject()

bull ReentrantLockndash По семантике эквивалентен synchronized

bull Рекурсивный захват проверка на threadID

bull Ставит потоки во внутреннюю очередь и делает park()

ndash Non-Fair (default)

bull Не гарантирует отсутствие starvation

bull Barging FIFO (CAS)

bull Лучшая производительность

ndash Fair

bull Гарантирует отсутствие starvation

bull FIFO

bull Честность в обмен на производительностьhttpgeecsoswegoedudlpapersaqspdf

37 copy JavaTechDays 2011 Oracle Corporation

Concurrencyатомарный счётчик

private AtomicInteger atomic = new AtomicInteger() private ReentrantLock lock = new ReentrantLock() private final Object intrinsicLock = new Object() private int primCounter = 0

GenerateMicroBenchmark public void testAtomicInteger() atomicincrementAndGet()

GenerateMicroBenchmark public void testReentrantLock() locklock() primCounter++ lockunlock()

GenerateMicroBenchmark public void testIntrinsicLock() synchronized (intrinsicLock) primCounter++

38 copy JavaTechDays 2011 Oracle Corporation

Concurrencyатомарный счётчик

0 16 32 48 64 80 96 112 128

1000

10000

100000

Atomic Counter Performance

Intrinsic AtomicInteger ReentrantLock

Threads

ops

sec

8x8 CPUs Solaris 6u25

39 copy JavaTechDays 2011 Oracle Corporation

ConcurrencyReentrantLock vs synchronized

bull Семантика одинаковаndash Требования к видимости памяти

ndash Рекурсивный

bull Плюсы jucRLndash Очередь потоков держится на стороне JVM

bull опционально FIFO-политика при захвате-освобождении

bull позволяет быть ldquoчестнымrdquo на любой платформе

ndash Barging FIFO policy

bull lock() может быть сразу удовлетворён даже если в очереди есть потоки

bull сильно улучшает производительность при конфликте блокировок

ndash Допускается несколько Condition

bull Минусы jucRLndash Нет scopeов требуется ручной unlock() через finally

bull Должно быть проще с ARM в JDK7

40 copy JavaTechDays 2011 Oracle Corporation

Concurrencyбесконфликтный захват

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

10000

20000

30000

40000

50000

60000

70000

80000

90000

100000

110000

120000

130000

140000

150000

Uncontended Lock Performance

intrinsic jucReentrantL (non-fair) jucReentrantL (fair)

Threads

op

sse

c

41 copy JavaTechDays 2011 Oracle Corporation

Concurrencyконфликтный захват

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

500

1000

1500

2000

2500

3000

3500

4000

4500

Contended Lock Performance

intrinsic jucReentrantL (non-fair) jucReentrantL (fair)

Threads

op

sse

c

43 copy 2011 JavaTechDays Oracle Corporation

bull hellip естьbull hellip работаетbull hellip работает хорошоbull hellip знает о железе всё

ndash Количество и тип CPUndash Поддерживаемые инcтрукции (SSEx AVX VIS)ndash Топологию памяти (в тч размеры кэшей и их характеристики)

bull hellip знает о приложении много всегоndash Иерархию загруженных классовndash Актуальную статистику создания объектовndash Горячий кодndash Какие ветвления исполнялисьndash Какие значения использовалисьndash Многое другое

bull hellip не боится использовать эти знания для компиляции

JITфакты

44 copy 2011 JavaTechDays Oracle Corporation

JITоптимизации

46 copy 2011 JavaTechDays Oracle Corporation

JITкак писать код

bull Используйте стандартные библиотекиndash Зачем писать собственный стандартный контейнер

bull Используйте высокоуровневый API ndash javautilndash javautilconcurrentndash NIO NIO2ndash вообще библиотеки

bull Код должен правильным и понятнымndash Сначала правильноndash Потом алгоритмически ldquoбыстроrdquondash Код не должен быть JIT-oriented

bull Правильно используйте возможности языкаndash EPIC FAIL штатная передача управления exceptionамиndash FAIL Возврат ldquoисключенияrdquo через return ltкод_ошибкиgtndash FAIL int вместо Enum или boolean

47 copy 2011 JavaTechDays Oracle Corporation

Как получить ассемблерный код метода

ndash Обычным дебаггером )

ndash JVMTI

ndash -XX+PrintAssemblybull httpwikissuncomdisplayHotSpotInternalsPrintAssembly

JITдля любопытных

54 copy JavaTechDays 2011 Oracle Corporation

StartupEclipse

bull Типичная конфигурацияndash 2x2 Intel i5 26 Ghz Ubuntu 1010 i686 JDK 6u25ndash Eclipse JDT (Galileo)

bull Типичные метрикиndash 6000 загруженных классовndash 1000 методов скомпилированоndash 512 Mb зарезервированного пространства в кучеndash 25 Mb кучи использовано после стартапа

bull Известные ldquoпроблемыrdquondash Загрузка и верификация классовndash JIT-компиляция

55 copy JavaTechDays 2011 Oracle Corporation

StartupEclipse

bull Метрика секунд на запуск-завершениеndash Файловые кеши прогреты практически нулевой дисковый IO

default CDS CDS + no-verify

абсолютное время

583 [574 592]

481[473 484]

461[456 474]

загрузка классов

501[491 511]

339[312 366]

301[294 308]

компиляция 051[043 059]

051[044 058]

051[042 060]

56 copy JavaTechDays 2011 Oracle Corporation

Startupдлинные приложения

bull Важно только для коротких приложенийndash Чем дольше работает приложение тем меньше удельные затраты на

загрузку классов и компиляцию

bull Пример 8 часа работает IntelliJ IDEA 10xndash 26600 классов загруженоndash 5315 методов скомпилировано

bull Загрузка классовndash Всего потрачено 202 с ~07 общего времениndash 10 мсек на класс

bull Компиляцияndash Всего потрачено 112 с ~003 общего времениndash 20 мсек на метод

57 copy JavaTechDays 2011 Oracle Corporation

Whats Next

bull Послушать ещёndash JavaOne Moscow (апрель 2011)

bull Проблема со слайдамиndash Найдите нас на конференцииndash Напишите нам письмо

bull Проблема с JDKndash httpopenjdkjavanetndash Задайте вопрос в OpenJDKndash а лучше сделайте патч и дайте его в OpenJDK на review

58 copy JavaTechDays 2011 Oracle Corporation

QA

Page 4: Java Platform Performance BoF - Aleksey Shipilëv · – 2x2 Intel i5 2.6 Ghz, Ubuntu 10.10 i686, JDK 6u25 • Три варианта эксперимента: – 1 экземпляр

7 copy JavaTechDays 2011 Oracle Corporation

Performance Engineeringанализ узких мест

bull Что ограничивает скорость работы приложения

bull CPUbull Ядро ОСbull IO (Сеть Диск)

9 copy JavaTechDays 2011 Oracle Corporation

Performance Engineeringанализ узких мест (tips)

bull Низкая утилизация CPUndash Высокая дисковая сетевая активностьndash Конфликт блокировокndash Конфликт ресурсов ОСndash Слабая параллелизация приложения

bull Высокая утилизация ядра ОСndash Частые блокировкиndash Частое обращение к ОС

bull Высокая утилизация CPU ndash Неоптимальная архитектура приложенияndash Неправильное использование APIndash Неоптимизированные горячие методыndash Неоптимальные настройки GC

10 copy JavaTechDays 2011 Oracle Corporation

Solaris Linux Windows Что смотрим

Сеть netstat dtrace netstat perfmon количество соединений объем трафика

Диск iostat dtrace iostat perfmon количество обращений к диску задержка

Память vmstat prstat dtrace

vmstat top perfmon подкачка страниц размер памяти

Процессы ps vmstat mpstat prstat dtrace

ps vmstat top perfmon количество нитей состояние нитей переключения контекста

Ядро ОС mpstat lockstat plockstat dtrace intrstat vmstat

vmstat perfmon kernel time блокировки системные вызовы прерывания

Performance Engineeringинструменты для анализа системы

11 copy JavaTechDays 2011 Oracle Corporation

Performance Engineeringtools tools tools again more tools

bull VisualVM ndash httpvisualvmdevjavanet

bull JRockit Mission Controlndash httpwwworaclecomtechnetworkmiddlewarejrockitmission-controlindexhtml

bull Sun Studio Analyzerndash httpwwworaclecomtechnetworkserver-storagesolarisstudiooverviewindexhtml

bull NetBeans Profilerndash httpwwwnetbeansorg

bull DTracendash httpwwworaclecomtechnetworksystemsdtracedtraceindexhtml

bull Ещё могут быть полезныndash JProbendash OptimizeItndash YourKit

13 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingна чём измерять производительность

ldquoмикроrdquoбенчмарки

синтетические бенчмарки

авто-сценарии реальных приложений

реальные приложения

релевантность плохая средняя хорошая отличная

расходы на разработку и поддержку

низкие средние средние высокие

расходы на запуск

низкие низкие средние высокие

сложность интерпретации результатов

очень сложно

средняя достаточно просто

сложно

14 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingнаша стратегия

bull Сделать реальные приложения быстрееndash Но слишком сложно поддерживать и запускатьndash Поэтому

bull Сфокусироваться на синтетических бенчмарках и авто-сценарияхndash SPECjbb SPECjvm SPECjAppServer SPECjEnterprisendash Glassfish Weblogic NetBeans и тпndash Большие in-house нагрузки

bull Пользоваться микробенчмарками с опаскойndash Иногда от них никуда не детьсяndash Очень легко написать очень легко запуститьndash Очень легко ldquoвыстрелить себе в ногуrdquondash что чуть ли не каждую неделю демонстрируется в профильных

блогах

15 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingитак вы решили написать свой бенчмарк

bull Опасайтесь типичных ошибокbull Дизайн эксперимента

ndash Что хотим измеритьndash Каким способом будем измерять

bull Реализация экспериментаndash Отсутствие прогрева ldquoмёртвый кодrdquo etcndash Многопоточность утилизацияndash Контроль переменных результат воспроизводитсяndash Контроль переменных результат вообще зависит от входов

bull Интерпретация результатовndash Что в итоге измерилиndash Значим ли результат

bull 1000 opssec против 1050 opssec ndash прирост или нет

16 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingближе к делу пример

bull Computer Language Benchmark Gamendash httpshootoutaliothdebianorgndash Самый известный полигон для расстрела невинных ног

bull Тест ldquoPiDigitsrdquondash Вычислить первые N цифр в десятичном разложении πndash Вычисляется приближение π специальным рядом

bull Требуется arbitrary precision для представления рациональных членов ряда

ndash Потенциально параллелизуемаndash Две версии Java-теста

bull Текущая использует GNU MP внутренне параллельна 240 строк кода Java + нативные врапперы + GMP

bull Предыдущая использует BigInteger не параллельна 130 строк кода plain Java

17 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingближе к делу пример

bull Computer Language Benchmark Gamendash httpshootoutaliothdebianorgndash Самый известный полигон для расстрела невинных ног

bull Тест ldquoPiDigitsrdquondash Вычислить первые N цифр в десятичном разложении πndash Вычисляется приближение π специальным рядом

bull Требуется arbitrary precision для представления рациональных членов ряда

ndash Потенциально параллелизуемаndash Две версии Java-теста

bull Текущая использует GNU MP внутренне параллельна 240 строк кода Java + нативные врапперы + GMP

bull Предыдущая использует BigInteger не параллельна 130 строк кода plain Java

18 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingближе к делу пример

bull Метрика время исполненияndash time java -server pidigits 1000

bull ldquoПрогреемrdquo

pidigitsjavasteady public static void main(String[] args) pidigits m = new pidigits(IntegerparseInt(args[0])) for (int i=0 ilt65 ++i) mpidigits(false) mpidigits(true)

19 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingближе к делу пример

bull Метрика время исполненияndash time java -server pidigits 1000

bull ldquoПрогреемrdquo

pidigitsjavasteady public static void main(String[] args) pidigits m = new pidigits(IntegerparseInt(args[0])) for (int i=0 ilt65 ++i) mpidigits(false) mpidigits(true)

20 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingближе к делу пример

bull Метрика время исполненияndash time java -server pidigits 1000

bull ldquoПрогреемrdquo

pidigitsjava public static void main(String[] args) pidigits m = new pidigits(IntegerparseInt(args[0])) for (int i=0 ilt19 ++i) mpidigits(false) mpidigits(true)

pidigitsjavasteady public static void main(String[] args) pidigits m = new pidigits(IntegerparseInt(args[0])) for (int i=0 ilt65 ++i) mpidigits(false) mpidigits(true)

21 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingв век многоядерных систем

bull Обычная платформаndash 2x2 Intel i5 26 Ghz Ubuntu 1010 i686 JDK 6u25

bull Три варианта экспериментаndash 1 экземпляр бенчмарка

bull по ldquoметодологии CLBGrdquo (+ корректный прогрев)

bull GMP будет использовать 1x4=4 потока

bull BI будет использовать 1x1=1 поток

ndash 4 экземпляра бенчмарка

bull чтобы утилизировать все ядра = снормировать на систему

bull GMP будет использовать 4х4=16 потоков

bull BI будет использовать 4x1=4 потока

ndash 16 потоков

bull ради одинаковой нагрузки на OS = снормировать на систему+OS

bull GMP будет использовать 4х4=16 потоков

bull BI будет работать в 16x1=16 потоков

bull Какой из них наиболее релевантен

22 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingа вот и данные

1 экземпляр 4 экземпляра 16 потоков

ldquoGMPrdquo

884[869 899]

1328 [1286 1371]

1328 [1286 1371]

ldquoBigIntegerrdquo

621 [619 624]

1346 [1335 1356]

1434 [1421 1446]

bull Метрика операции в секундуndash 20 итерацийndash [a b] ndash доверительный интервал на 95

24 copy JavaTechDays 2011 Oracle Corporation

Java 7 Java 8что ожидать в области производительности

bull Java 7ndash invokedynamicndash NIO2ndash Concurrency and Collection updates (ForkJoin)ndash XRender pipeline for Java2D (client)

bull Java 8 (или позже)ndash Модульностьndash -выражения (замыкания)ndash Collection updates (filter map reduce)

25 copy JavaTechDays 2011 Oracle Corporation

bull Мешает ли улучшать производительность JVMndash Да поэтому иногда расширяемся

bull invokedynamicbull Модульность

bull Стоит ли расширяться по первому требованию ndash Нет развитие JVMJIT реализация новых методов оптимизации

позволяет получить бОльший выигрышbull Вложенные классыbull Reflection

Обратная совместимость

26 copy JavaTechDays 2011 Oracle Corporation

Solaris

Лучшая ОС для Javaугадайте какая

bull Высокопроизводительный TCPIP стекndash low-latencyndash up to 50 faster

bull DTracendash мониторинг

bull NUMAndash MPO Memory Placement Optimization

bull Large Pagesndash Автоматическая аллокацияndash Разные размеры

27 copy JavaTechDays 2011 Oracle Corporation

hellip and beyondнастройка параметров JVM

bull Что настраиватьndash httpblogssuncomwattresourcejvm-options-listhtml

ndash httpwwworaclecomtechnetworkjavajavasetechvmoptions-jsp-140102html

bull JVM сама подбирает оптимальные параметры своей работыndash Server vs Client ndash Large pages (Solaris)ndash CompressedOops (64-bit VM)

bull Так что же настраиватьndash GCHeap tuningndash -XX+UseNUMA (Solaris Linux)ndash -XX+UseLargePages (Linux Windows)

bull httpwwworaclecomtechnetworkjavajavasetechlargememory-jsp-137182html

bull Не забытьndash Использовать последнюю версию JDK

29 copy JavaTechDays 2011 Oracle Corporation

Concurrencyэлементная база

bull OS Threadingndash мьютексы

bull mutex_lock()mutex_unlock()ndash conditional waits

bull cond_wait()cond_signal()bull WaitForSingleObject

bull Compare-and-Swap (CAS)ndash CAS(x1 x2 x3) = if (x1 == x2) x1 = x3 ndash атомарная операция поддерживаемая в ldquoжелезеrdquo из нескольких

одновременных CASов успешно завершается только одинndash Миф локальный CAS блокирует шину и стоит больше на

многопроцессорных системах ndash Факт глобальный CAS требует трафика на шине

httpblogssuncomdaveentrybiased_locking_in_hotspot

30 copy JavaTechDays 2011 Oracle Corporation

Concurrencyatomics

bull javautilconcurrentAtomicndash обеспечивают атомарные операции над примитивами и указателямиndash альтернатива synchronized или Lockи

bull Трюк в использовании CASаndash Изменение состояния атомика делается при помощи одного CASаndash Чтение состояния не требует CASа

public final int incrementAndGet() for () int current = get() int next = current + 1 if (compareAndSet(current next)) return next

mov ecxedxmov 0x8(ecx)eaxlea 0x8(ecx)edimov eaxecxinc ecxlock cmpxchg ecx(edi)mov $0x0ebxjne [ok]mov $0x1ebxtest ebxebxje [ok]

31 copy JavaTechDays 2011 Oracle Corporation

Concurrencyvolatile

bull Volatile определяет порядок чтения-записей в полеndash Точная семантика определена в Java Memory Model

bull НЕ обеспечивает атомарностиndash Реализуется расстановкой барьеров

bull Какие из них вставятся в код зависит от Hardware Memory Modelbull Эффект барьера зависит от HMM

PUSHL EBPSUB ESP8MOV EBX[ECX + 12]MEMBAR-acquireMEMBAR-releaseINC EBXMOV [ECX + 12]EBXMEMBAR-volatileLOCK ADDL [ESP + 0] 0ADD ESP8POPL EBPTEST PollPageEAXRET

push ebpsub $0x8espmov 0xc(ecx)ebxinc ebxmov ebx0xc(ecx)lock addl $0x0(esp)add $0x8esppop ebptest eax0xb779c000ret

httpgoswegoedudljmmcookbookhtml

32 copy JavaTechDays 2011 Oracle Corporation

Concurrencyvolatile-счётчик

public class VolatileTest

private int counter = 0 private volatile int volatileCounter = 0

GenerateMicroBenchmark public void testOrdinary() counter++

GenerateMicroBenchmark public void testVolatile() volatileCounter++

33 copy JavaTechDays 2011 Oracle Corporation

Concurrencyбесконфликтный volatile-счётчик

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

500000

1000000

1500000

2000000

2500000

3000000

3500000

Thread-local counter performance

ordinary volatile

Threads

op

ss

ec

34 copy JavaTechDays 2011 Oracle Corporation

Concurrencyконфликтный volatile-счётчик

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

100000

200000

300000

400000

500000

600000

700000

800000

900000

Global counter performance

ordinary volatile

Threads

op

ss

ec

35 copy JavaTechDays 2011 Oracle Corporation

Concurrencyintrinsic synchronization

bull synchronized(object) bull 4 состояния

ndash Initbull Начальное ldquoнеопределённоеrdquo состояние

ndash Biasedbull Захватывается одним ldquoвладеющимrdquo потоком нет конфликтовbull Захват владельцем проверка на threadIDbull Захват не-владельцем переход либо в Biased либо в Thin

ndash Thinbull Захватывается несколькими потоками но конфликтов нетbull Захват CASbull Конфликтный захват переход в Fat

ndash Fatbull Захватывается несколькими потоками конфликт на блокировкеbull Вызов примитива синхронизации из ОС

36 copy JavaTechDays 2011 Oracle Corporation

ConcurrencyjavautilconcurrentLock

bull Построены на базе jucAbstractQueueSynchronizerndash Использует атомики

bull CAS

ndash Использует Unsafepark()unpark()

bull интринзики для cond_wait()cond_signal()WaitForSingleObject()

bull ReentrantLockndash По семантике эквивалентен synchronized

bull Рекурсивный захват проверка на threadID

bull Ставит потоки во внутреннюю очередь и делает park()

ndash Non-Fair (default)

bull Не гарантирует отсутствие starvation

bull Barging FIFO (CAS)

bull Лучшая производительность

ndash Fair

bull Гарантирует отсутствие starvation

bull FIFO

bull Честность в обмен на производительностьhttpgeecsoswegoedudlpapersaqspdf

37 copy JavaTechDays 2011 Oracle Corporation

Concurrencyатомарный счётчик

private AtomicInteger atomic = new AtomicInteger() private ReentrantLock lock = new ReentrantLock() private final Object intrinsicLock = new Object() private int primCounter = 0

GenerateMicroBenchmark public void testAtomicInteger() atomicincrementAndGet()

GenerateMicroBenchmark public void testReentrantLock() locklock() primCounter++ lockunlock()

GenerateMicroBenchmark public void testIntrinsicLock() synchronized (intrinsicLock) primCounter++

38 copy JavaTechDays 2011 Oracle Corporation

Concurrencyатомарный счётчик

0 16 32 48 64 80 96 112 128

1000

10000

100000

Atomic Counter Performance

Intrinsic AtomicInteger ReentrantLock

Threads

ops

sec

8x8 CPUs Solaris 6u25

39 copy JavaTechDays 2011 Oracle Corporation

ConcurrencyReentrantLock vs synchronized

bull Семантика одинаковаndash Требования к видимости памяти

ndash Рекурсивный

bull Плюсы jucRLndash Очередь потоков держится на стороне JVM

bull опционально FIFO-политика при захвате-освобождении

bull позволяет быть ldquoчестнымrdquo на любой платформе

ndash Barging FIFO policy

bull lock() может быть сразу удовлетворён даже если в очереди есть потоки

bull сильно улучшает производительность при конфликте блокировок

ndash Допускается несколько Condition

bull Минусы jucRLndash Нет scopeов требуется ручной unlock() через finally

bull Должно быть проще с ARM в JDK7

40 copy JavaTechDays 2011 Oracle Corporation

Concurrencyбесконфликтный захват

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

10000

20000

30000

40000

50000

60000

70000

80000

90000

100000

110000

120000

130000

140000

150000

Uncontended Lock Performance

intrinsic jucReentrantL (non-fair) jucReentrantL (fair)

Threads

op

sse

c

41 copy JavaTechDays 2011 Oracle Corporation

Concurrencyконфликтный захват

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

500

1000

1500

2000

2500

3000

3500

4000

4500

Contended Lock Performance

intrinsic jucReentrantL (non-fair) jucReentrantL (fair)

Threads

op

sse

c

43 copy 2011 JavaTechDays Oracle Corporation

bull hellip естьbull hellip работаетbull hellip работает хорошоbull hellip знает о железе всё

ndash Количество и тип CPUndash Поддерживаемые инcтрукции (SSEx AVX VIS)ndash Топологию памяти (в тч размеры кэшей и их характеристики)

bull hellip знает о приложении много всегоndash Иерархию загруженных классовndash Актуальную статистику создания объектовndash Горячий кодndash Какие ветвления исполнялисьndash Какие значения использовалисьndash Многое другое

bull hellip не боится использовать эти знания для компиляции

JITфакты

44 copy 2011 JavaTechDays Oracle Corporation

JITоптимизации

46 copy 2011 JavaTechDays Oracle Corporation

JITкак писать код

bull Используйте стандартные библиотекиndash Зачем писать собственный стандартный контейнер

bull Используйте высокоуровневый API ndash javautilndash javautilconcurrentndash NIO NIO2ndash вообще библиотеки

bull Код должен правильным и понятнымndash Сначала правильноndash Потом алгоритмически ldquoбыстроrdquondash Код не должен быть JIT-oriented

bull Правильно используйте возможности языкаndash EPIC FAIL штатная передача управления exceptionамиndash FAIL Возврат ldquoисключенияrdquo через return ltкод_ошибкиgtndash FAIL int вместо Enum или boolean

47 copy 2011 JavaTechDays Oracle Corporation

Как получить ассемблерный код метода

ndash Обычным дебаггером )

ndash JVMTI

ndash -XX+PrintAssemblybull httpwikissuncomdisplayHotSpotInternalsPrintAssembly

JITдля любопытных

54 copy JavaTechDays 2011 Oracle Corporation

StartupEclipse

bull Типичная конфигурацияndash 2x2 Intel i5 26 Ghz Ubuntu 1010 i686 JDK 6u25ndash Eclipse JDT (Galileo)

bull Типичные метрикиndash 6000 загруженных классовndash 1000 методов скомпилированоndash 512 Mb зарезервированного пространства в кучеndash 25 Mb кучи использовано после стартапа

bull Известные ldquoпроблемыrdquondash Загрузка и верификация классовndash JIT-компиляция

55 copy JavaTechDays 2011 Oracle Corporation

StartupEclipse

bull Метрика секунд на запуск-завершениеndash Файловые кеши прогреты практически нулевой дисковый IO

default CDS CDS + no-verify

абсолютное время

583 [574 592]

481[473 484]

461[456 474]

загрузка классов

501[491 511]

339[312 366]

301[294 308]

компиляция 051[043 059]

051[044 058]

051[042 060]

56 copy JavaTechDays 2011 Oracle Corporation

Startupдлинные приложения

bull Важно только для коротких приложенийndash Чем дольше работает приложение тем меньше удельные затраты на

загрузку классов и компиляцию

bull Пример 8 часа работает IntelliJ IDEA 10xndash 26600 классов загруженоndash 5315 методов скомпилировано

bull Загрузка классовndash Всего потрачено 202 с ~07 общего времениndash 10 мсек на класс

bull Компиляцияndash Всего потрачено 112 с ~003 общего времениndash 20 мсек на метод

57 copy JavaTechDays 2011 Oracle Corporation

Whats Next

bull Послушать ещёndash JavaOne Moscow (апрель 2011)

bull Проблема со слайдамиndash Найдите нас на конференцииndash Напишите нам письмо

bull Проблема с JDKndash httpopenjdkjavanetndash Задайте вопрос в OpenJDKndash а лучше сделайте патч и дайте его в OpenJDK на review

58 copy JavaTechDays 2011 Oracle Corporation

QA

Page 5: Java Platform Performance BoF - Aleksey Shipilëv · – 2x2 Intel i5 2.6 Ghz, Ubuntu 10.10 i686, JDK 6u25 • Три варианта эксперимента: – 1 экземпляр

9 copy JavaTechDays 2011 Oracle Corporation

Performance Engineeringанализ узких мест (tips)

bull Низкая утилизация CPUndash Высокая дисковая сетевая активностьndash Конфликт блокировокndash Конфликт ресурсов ОСndash Слабая параллелизация приложения

bull Высокая утилизация ядра ОСndash Частые блокировкиndash Частое обращение к ОС

bull Высокая утилизация CPU ndash Неоптимальная архитектура приложенияndash Неправильное использование APIndash Неоптимизированные горячие методыndash Неоптимальные настройки GC

10 copy JavaTechDays 2011 Oracle Corporation

Solaris Linux Windows Что смотрим

Сеть netstat dtrace netstat perfmon количество соединений объем трафика

Диск iostat dtrace iostat perfmon количество обращений к диску задержка

Память vmstat prstat dtrace

vmstat top perfmon подкачка страниц размер памяти

Процессы ps vmstat mpstat prstat dtrace

ps vmstat top perfmon количество нитей состояние нитей переключения контекста

Ядро ОС mpstat lockstat plockstat dtrace intrstat vmstat

vmstat perfmon kernel time блокировки системные вызовы прерывания

Performance Engineeringинструменты для анализа системы

11 copy JavaTechDays 2011 Oracle Corporation

Performance Engineeringtools tools tools again more tools

bull VisualVM ndash httpvisualvmdevjavanet

bull JRockit Mission Controlndash httpwwworaclecomtechnetworkmiddlewarejrockitmission-controlindexhtml

bull Sun Studio Analyzerndash httpwwworaclecomtechnetworkserver-storagesolarisstudiooverviewindexhtml

bull NetBeans Profilerndash httpwwwnetbeansorg

bull DTracendash httpwwworaclecomtechnetworksystemsdtracedtraceindexhtml

bull Ещё могут быть полезныndash JProbendash OptimizeItndash YourKit

13 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingна чём измерять производительность

ldquoмикроrdquoбенчмарки

синтетические бенчмарки

авто-сценарии реальных приложений

реальные приложения

релевантность плохая средняя хорошая отличная

расходы на разработку и поддержку

низкие средние средние высокие

расходы на запуск

низкие низкие средние высокие

сложность интерпретации результатов

очень сложно

средняя достаточно просто

сложно

14 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingнаша стратегия

bull Сделать реальные приложения быстрееndash Но слишком сложно поддерживать и запускатьndash Поэтому

bull Сфокусироваться на синтетических бенчмарках и авто-сценарияхndash SPECjbb SPECjvm SPECjAppServer SPECjEnterprisendash Glassfish Weblogic NetBeans и тпndash Большие in-house нагрузки

bull Пользоваться микробенчмарками с опаскойndash Иногда от них никуда не детьсяndash Очень легко написать очень легко запуститьndash Очень легко ldquoвыстрелить себе в ногуrdquondash что чуть ли не каждую неделю демонстрируется в профильных

блогах

15 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingитак вы решили написать свой бенчмарк

bull Опасайтесь типичных ошибокbull Дизайн эксперимента

ndash Что хотим измеритьndash Каким способом будем измерять

bull Реализация экспериментаndash Отсутствие прогрева ldquoмёртвый кодrdquo etcndash Многопоточность утилизацияndash Контроль переменных результат воспроизводитсяndash Контроль переменных результат вообще зависит от входов

bull Интерпретация результатовndash Что в итоге измерилиndash Значим ли результат

bull 1000 opssec против 1050 opssec ndash прирост или нет

16 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingближе к делу пример

bull Computer Language Benchmark Gamendash httpshootoutaliothdebianorgndash Самый известный полигон для расстрела невинных ног

bull Тест ldquoPiDigitsrdquondash Вычислить первые N цифр в десятичном разложении πndash Вычисляется приближение π специальным рядом

bull Требуется arbitrary precision для представления рациональных членов ряда

ndash Потенциально параллелизуемаndash Две версии Java-теста

bull Текущая использует GNU MP внутренне параллельна 240 строк кода Java + нативные врапперы + GMP

bull Предыдущая использует BigInteger не параллельна 130 строк кода plain Java

17 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingближе к делу пример

bull Computer Language Benchmark Gamendash httpshootoutaliothdebianorgndash Самый известный полигон для расстрела невинных ног

bull Тест ldquoPiDigitsrdquondash Вычислить первые N цифр в десятичном разложении πndash Вычисляется приближение π специальным рядом

bull Требуется arbitrary precision для представления рациональных членов ряда

ndash Потенциально параллелизуемаndash Две версии Java-теста

bull Текущая использует GNU MP внутренне параллельна 240 строк кода Java + нативные врапперы + GMP

bull Предыдущая использует BigInteger не параллельна 130 строк кода plain Java

18 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingближе к делу пример

bull Метрика время исполненияndash time java -server pidigits 1000

bull ldquoПрогреемrdquo

pidigitsjavasteady public static void main(String[] args) pidigits m = new pidigits(IntegerparseInt(args[0])) for (int i=0 ilt65 ++i) mpidigits(false) mpidigits(true)

19 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingближе к делу пример

bull Метрика время исполненияndash time java -server pidigits 1000

bull ldquoПрогреемrdquo

pidigitsjavasteady public static void main(String[] args) pidigits m = new pidigits(IntegerparseInt(args[0])) for (int i=0 ilt65 ++i) mpidigits(false) mpidigits(true)

20 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingближе к делу пример

bull Метрика время исполненияndash time java -server pidigits 1000

bull ldquoПрогреемrdquo

pidigitsjava public static void main(String[] args) pidigits m = new pidigits(IntegerparseInt(args[0])) for (int i=0 ilt19 ++i) mpidigits(false) mpidigits(true)

pidigitsjavasteady public static void main(String[] args) pidigits m = new pidigits(IntegerparseInt(args[0])) for (int i=0 ilt65 ++i) mpidigits(false) mpidigits(true)

21 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingв век многоядерных систем

bull Обычная платформаndash 2x2 Intel i5 26 Ghz Ubuntu 1010 i686 JDK 6u25

bull Три варианта экспериментаndash 1 экземпляр бенчмарка

bull по ldquoметодологии CLBGrdquo (+ корректный прогрев)

bull GMP будет использовать 1x4=4 потока

bull BI будет использовать 1x1=1 поток

ndash 4 экземпляра бенчмарка

bull чтобы утилизировать все ядра = снормировать на систему

bull GMP будет использовать 4х4=16 потоков

bull BI будет использовать 4x1=4 потока

ndash 16 потоков

bull ради одинаковой нагрузки на OS = снормировать на систему+OS

bull GMP будет использовать 4х4=16 потоков

bull BI будет работать в 16x1=16 потоков

bull Какой из них наиболее релевантен

22 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingа вот и данные

1 экземпляр 4 экземпляра 16 потоков

ldquoGMPrdquo

884[869 899]

1328 [1286 1371]

1328 [1286 1371]

ldquoBigIntegerrdquo

621 [619 624]

1346 [1335 1356]

1434 [1421 1446]

bull Метрика операции в секундуndash 20 итерацийndash [a b] ndash доверительный интервал на 95

24 copy JavaTechDays 2011 Oracle Corporation

Java 7 Java 8что ожидать в области производительности

bull Java 7ndash invokedynamicndash NIO2ndash Concurrency and Collection updates (ForkJoin)ndash XRender pipeline for Java2D (client)

bull Java 8 (или позже)ndash Модульностьndash -выражения (замыкания)ndash Collection updates (filter map reduce)

25 copy JavaTechDays 2011 Oracle Corporation

bull Мешает ли улучшать производительность JVMndash Да поэтому иногда расширяемся

bull invokedynamicbull Модульность

bull Стоит ли расширяться по первому требованию ndash Нет развитие JVMJIT реализация новых методов оптимизации

позволяет получить бОльший выигрышbull Вложенные классыbull Reflection

Обратная совместимость

26 copy JavaTechDays 2011 Oracle Corporation

Solaris

Лучшая ОС для Javaугадайте какая

bull Высокопроизводительный TCPIP стекndash low-latencyndash up to 50 faster

bull DTracendash мониторинг

bull NUMAndash MPO Memory Placement Optimization

bull Large Pagesndash Автоматическая аллокацияndash Разные размеры

27 copy JavaTechDays 2011 Oracle Corporation

hellip and beyondнастройка параметров JVM

bull Что настраиватьndash httpblogssuncomwattresourcejvm-options-listhtml

ndash httpwwworaclecomtechnetworkjavajavasetechvmoptions-jsp-140102html

bull JVM сама подбирает оптимальные параметры своей работыndash Server vs Client ndash Large pages (Solaris)ndash CompressedOops (64-bit VM)

bull Так что же настраиватьndash GCHeap tuningndash -XX+UseNUMA (Solaris Linux)ndash -XX+UseLargePages (Linux Windows)

bull httpwwworaclecomtechnetworkjavajavasetechlargememory-jsp-137182html

bull Не забытьndash Использовать последнюю версию JDK

29 copy JavaTechDays 2011 Oracle Corporation

Concurrencyэлементная база

bull OS Threadingndash мьютексы

bull mutex_lock()mutex_unlock()ndash conditional waits

bull cond_wait()cond_signal()bull WaitForSingleObject

bull Compare-and-Swap (CAS)ndash CAS(x1 x2 x3) = if (x1 == x2) x1 = x3 ndash атомарная операция поддерживаемая в ldquoжелезеrdquo из нескольких

одновременных CASов успешно завершается только одинndash Миф локальный CAS блокирует шину и стоит больше на

многопроцессорных системах ndash Факт глобальный CAS требует трафика на шине

httpblogssuncomdaveentrybiased_locking_in_hotspot

30 copy JavaTechDays 2011 Oracle Corporation

Concurrencyatomics

bull javautilconcurrentAtomicndash обеспечивают атомарные операции над примитивами и указателямиndash альтернатива synchronized или Lockи

bull Трюк в использовании CASаndash Изменение состояния атомика делается при помощи одного CASаndash Чтение состояния не требует CASа

public final int incrementAndGet() for () int current = get() int next = current + 1 if (compareAndSet(current next)) return next

mov ecxedxmov 0x8(ecx)eaxlea 0x8(ecx)edimov eaxecxinc ecxlock cmpxchg ecx(edi)mov $0x0ebxjne [ok]mov $0x1ebxtest ebxebxje [ok]

31 copy JavaTechDays 2011 Oracle Corporation

Concurrencyvolatile

bull Volatile определяет порядок чтения-записей в полеndash Точная семантика определена в Java Memory Model

bull НЕ обеспечивает атомарностиndash Реализуется расстановкой барьеров

bull Какие из них вставятся в код зависит от Hardware Memory Modelbull Эффект барьера зависит от HMM

PUSHL EBPSUB ESP8MOV EBX[ECX + 12]MEMBAR-acquireMEMBAR-releaseINC EBXMOV [ECX + 12]EBXMEMBAR-volatileLOCK ADDL [ESP + 0] 0ADD ESP8POPL EBPTEST PollPageEAXRET

push ebpsub $0x8espmov 0xc(ecx)ebxinc ebxmov ebx0xc(ecx)lock addl $0x0(esp)add $0x8esppop ebptest eax0xb779c000ret

httpgoswegoedudljmmcookbookhtml

32 copy JavaTechDays 2011 Oracle Corporation

Concurrencyvolatile-счётчик

public class VolatileTest

private int counter = 0 private volatile int volatileCounter = 0

GenerateMicroBenchmark public void testOrdinary() counter++

GenerateMicroBenchmark public void testVolatile() volatileCounter++

33 copy JavaTechDays 2011 Oracle Corporation

Concurrencyбесконфликтный volatile-счётчик

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

500000

1000000

1500000

2000000

2500000

3000000

3500000

Thread-local counter performance

ordinary volatile

Threads

op

ss

ec

34 copy JavaTechDays 2011 Oracle Corporation

Concurrencyконфликтный volatile-счётчик

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

100000

200000

300000

400000

500000

600000

700000

800000

900000

Global counter performance

ordinary volatile

Threads

op

ss

ec

35 copy JavaTechDays 2011 Oracle Corporation

Concurrencyintrinsic synchronization

bull synchronized(object) bull 4 состояния

ndash Initbull Начальное ldquoнеопределённоеrdquo состояние

ndash Biasedbull Захватывается одним ldquoвладеющимrdquo потоком нет конфликтовbull Захват владельцем проверка на threadIDbull Захват не-владельцем переход либо в Biased либо в Thin

ndash Thinbull Захватывается несколькими потоками но конфликтов нетbull Захват CASbull Конфликтный захват переход в Fat

ndash Fatbull Захватывается несколькими потоками конфликт на блокировкеbull Вызов примитива синхронизации из ОС

36 copy JavaTechDays 2011 Oracle Corporation

ConcurrencyjavautilconcurrentLock

bull Построены на базе jucAbstractQueueSynchronizerndash Использует атомики

bull CAS

ndash Использует Unsafepark()unpark()

bull интринзики для cond_wait()cond_signal()WaitForSingleObject()

bull ReentrantLockndash По семантике эквивалентен synchronized

bull Рекурсивный захват проверка на threadID

bull Ставит потоки во внутреннюю очередь и делает park()

ndash Non-Fair (default)

bull Не гарантирует отсутствие starvation

bull Barging FIFO (CAS)

bull Лучшая производительность

ndash Fair

bull Гарантирует отсутствие starvation

bull FIFO

bull Честность в обмен на производительностьhttpgeecsoswegoedudlpapersaqspdf

37 copy JavaTechDays 2011 Oracle Corporation

Concurrencyатомарный счётчик

private AtomicInteger atomic = new AtomicInteger() private ReentrantLock lock = new ReentrantLock() private final Object intrinsicLock = new Object() private int primCounter = 0

GenerateMicroBenchmark public void testAtomicInteger() atomicincrementAndGet()

GenerateMicroBenchmark public void testReentrantLock() locklock() primCounter++ lockunlock()

GenerateMicroBenchmark public void testIntrinsicLock() synchronized (intrinsicLock) primCounter++

38 copy JavaTechDays 2011 Oracle Corporation

Concurrencyатомарный счётчик

0 16 32 48 64 80 96 112 128

1000

10000

100000

Atomic Counter Performance

Intrinsic AtomicInteger ReentrantLock

Threads

ops

sec

8x8 CPUs Solaris 6u25

39 copy JavaTechDays 2011 Oracle Corporation

ConcurrencyReentrantLock vs synchronized

bull Семантика одинаковаndash Требования к видимости памяти

ndash Рекурсивный

bull Плюсы jucRLndash Очередь потоков держится на стороне JVM

bull опционально FIFO-политика при захвате-освобождении

bull позволяет быть ldquoчестнымrdquo на любой платформе

ndash Barging FIFO policy

bull lock() может быть сразу удовлетворён даже если в очереди есть потоки

bull сильно улучшает производительность при конфликте блокировок

ndash Допускается несколько Condition

bull Минусы jucRLndash Нет scopeов требуется ручной unlock() через finally

bull Должно быть проще с ARM в JDK7

40 copy JavaTechDays 2011 Oracle Corporation

Concurrencyбесконфликтный захват

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

10000

20000

30000

40000

50000

60000

70000

80000

90000

100000

110000

120000

130000

140000

150000

Uncontended Lock Performance

intrinsic jucReentrantL (non-fair) jucReentrantL (fair)

Threads

op

sse

c

41 copy JavaTechDays 2011 Oracle Corporation

Concurrencyконфликтный захват

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

500

1000

1500

2000

2500

3000

3500

4000

4500

Contended Lock Performance

intrinsic jucReentrantL (non-fair) jucReentrantL (fair)

Threads

op

sse

c

43 copy 2011 JavaTechDays Oracle Corporation

bull hellip естьbull hellip работаетbull hellip работает хорошоbull hellip знает о железе всё

ndash Количество и тип CPUndash Поддерживаемые инcтрукции (SSEx AVX VIS)ndash Топологию памяти (в тч размеры кэшей и их характеристики)

bull hellip знает о приложении много всегоndash Иерархию загруженных классовndash Актуальную статистику создания объектовndash Горячий кодndash Какие ветвления исполнялисьndash Какие значения использовалисьndash Многое другое

bull hellip не боится использовать эти знания для компиляции

JITфакты

44 copy 2011 JavaTechDays Oracle Corporation

JITоптимизации

46 copy 2011 JavaTechDays Oracle Corporation

JITкак писать код

bull Используйте стандартные библиотекиndash Зачем писать собственный стандартный контейнер

bull Используйте высокоуровневый API ndash javautilndash javautilconcurrentndash NIO NIO2ndash вообще библиотеки

bull Код должен правильным и понятнымndash Сначала правильноndash Потом алгоритмически ldquoбыстроrdquondash Код не должен быть JIT-oriented

bull Правильно используйте возможности языкаndash EPIC FAIL штатная передача управления exceptionамиndash FAIL Возврат ldquoисключенияrdquo через return ltкод_ошибкиgtndash FAIL int вместо Enum или boolean

47 copy 2011 JavaTechDays Oracle Corporation

Как получить ассемблерный код метода

ndash Обычным дебаггером )

ndash JVMTI

ndash -XX+PrintAssemblybull httpwikissuncomdisplayHotSpotInternalsPrintAssembly

JITдля любопытных

54 copy JavaTechDays 2011 Oracle Corporation

StartupEclipse

bull Типичная конфигурацияndash 2x2 Intel i5 26 Ghz Ubuntu 1010 i686 JDK 6u25ndash Eclipse JDT (Galileo)

bull Типичные метрикиndash 6000 загруженных классовndash 1000 методов скомпилированоndash 512 Mb зарезервированного пространства в кучеndash 25 Mb кучи использовано после стартапа

bull Известные ldquoпроблемыrdquondash Загрузка и верификация классовndash JIT-компиляция

55 copy JavaTechDays 2011 Oracle Corporation

StartupEclipse

bull Метрика секунд на запуск-завершениеndash Файловые кеши прогреты практически нулевой дисковый IO

default CDS CDS + no-verify

абсолютное время

583 [574 592]

481[473 484]

461[456 474]

загрузка классов

501[491 511]

339[312 366]

301[294 308]

компиляция 051[043 059]

051[044 058]

051[042 060]

56 copy JavaTechDays 2011 Oracle Corporation

Startupдлинные приложения

bull Важно только для коротких приложенийndash Чем дольше работает приложение тем меньше удельные затраты на

загрузку классов и компиляцию

bull Пример 8 часа работает IntelliJ IDEA 10xndash 26600 классов загруженоndash 5315 методов скомпилировано

bull Загрузка классовndash Всего потрачено 202 с ~07 общего времениndash 10 мсек на класс

bull Компиляцияndash Всего потрачено 112 с ~003 общего времениndash 20 мсек на метод

57 copy JavaTechDays 2011 Oracle Corporation

Whats Next

bull Послушать ещёndash JavaOne Moscow (апрель 2011)

bull Проблема со слайдамиndash Найдите нас на конференцииndash Напишите нам письмо

bull Проблема с JDKndash httpopenjdkjavanetndash Задайте вопрос в OpenJDKndash а лучше сделайте патч и дайте его в OpenJDK на review

58 copy JavaTechDays 2011 Oracle Corporation

QA

Page 6: Java Platform Performance BoF - Aleksey Shipilëv · – 2x2 Intel i5 2.6 Ghz, Ubuntu 10.10 i686, JDK 6u25 • Три варианта эксперимента: – 1 экземпляр

10 copy JavaTechDays 2011 Oracle Corporation

Solaris Linux Windows Что смотрим

Сеть netstat dtrace netstat perfmon количество соединений объем трафика

Диск iostat dtrace iostat perfmon количество обращений к диску задержка

Память vmstat prstat dtrace

vmstat top perfmon подкачка страниц размер памяти

Процессы ps vmstat mpstat prstat dtrace

ps vmstat top perfmon количество нитей состояние нитей переключения контекста

Ядро ОС mpstat lockstat plockstat dtrace intrstat vmstat

vmstat perfmon kernel time блокировки системные вызовы прерывания

Performance Engineeringинструменты для анализа системы

11 copy JavaTechDays 2011 Oracle Corporation

Performance Engineeringtools tools tools again more tools

bull VisualVM ndash httpvisualvmdevjavanet

bull JRockit Mission Controlndash httpwwworaclecomtechnetworkmiddlewarejrockitmission-controlindexhtml

bull Sun Studio Analyzerndash httpwwworaclecomtechnetworkserver-storagesolarisstudiooverviewindexhtml

bull NetBeans Profilerndash httpwwwnetbeansorg

bull DTracendash httpwwworaclecomtechnetworksystemsdtracedtraceindexhtml

bull Ещё могут быть полезныndash JProbendash OptimizeItndash YourKit

13 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingна чём измерять производительность

ldquoмикроrdquoбенчмарки

синтетические бенчмарки

авто-сценарии реальных приложений

реальные приложения

релевантность плохая средняя хорошая отличная

расходы на разработку и поддержку

низкие средние средние высокие

расходы на запуск

низкие низкие средние высокие

сложность интерпретации результатов

очень сложно

средняя достаточно просто

сложно

14 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingнаша стратегия

bull Сделать реальные приложения быстрееndash Но слишком сложно поддерживать и запускатьndash Поэтому

bull Сфокусироваться на синтетических бенчмарках и авто-сценарияхndash SPECjbb SPECjvm SPECjAppServer SPECjEnterprisendash Glassfish Weblogic NetBeans и тпndash Большие in-house нагрузки

bull Пользоваться микробенчмарками с опаскойndash Иногда от них никуда не детьсяndash Очень легко написать очень легко запуститьndash Очень легко ldquoвыстрелить себе в ногуrdquondash что чуть ли не каждую неделю демонстрируется в профильных

блогах

15 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingитак вы решили написать свой бенчмарк

bull Опасайтесь типичных ошибокbull Дизайн эксперимента

ndash Что хотим измеритьndash Каким способом будем измерять

bull Реализация экспериментаndash Отсутствие прогрева ldquoмёртвый кодrdquo etcndash Многопоточность утилизацияndash Контроль переменных результат воспроизводитсяndash Контроль переменных результат вообще зависит от входов

bull Интерпретация результатовndash Что в итоге измерилиndash Значим ли результат

bull 1000 opssec против 1050 opssec ndash прирост или нет

16 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingближе к делу пример

bull Computer Language Benchmark Gamendash httpshootoutaliothdebianorgndash Самый известный полигон для расстрела невинных ног

bull Тест ldquoPiDigitsrdquondash Вычислить первые N цифр в десятичном разложении πndash Вычисляется приближение π специальным рядом

bull Требуется arbitrary precision для представления рациональных членов ряда

ndash Потенциально параллелизуемаndash Две версии Java-теста

bull Текущая использует GNU MP внутренне параллельна 240 строк кода Java + нативные врапперы + GMP

bull Предыдущая использует BigInteger не параллельна 130 строк кода plain Java

17 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingближе к делу пример

bull Computer Language Benchmark Gamendash httpshootoutaliothdebianorgndash Самый известный полигон для расстрела невинных ног

bull Тест ldquoPiDigitsrdquondash Вычислить первые N цифр в десятичном разложении πndash Вычисляется приближение π специальным рядом

bull Требуется arbitrary precision для представления рациональных членов ряда

ndash Потенциально параллелизуемаndash Две версии Java-теста

bull Текущая использует GNU MP внутренне параллельна 240 строк кода Java + нативные врапперы + GMP

bull Предыдущая использует BigInteger не параллельна 130 строк кода plain Java

18 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingближе к делу пример

bull Метрика время исполненияndash time java -server pidigits 1000

bull ldquoПрогреемrdquo

pidigitsjavasteady public static void main(String[] args) pidigits m = new pidigits(IntegerparseInt(args[0])) for (int i=0 ilt65 ++i) mpidigits(false) mpidigits(true)

19 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingближе к делу пример

bull Метрика время исполненияndash time java -server pidigits 1000

bull ldquoПрогреемrdquo

pidigitsjavasteady public static void main(String[] args) pidigits m = new pidigits(IntegerparseInt(args[0])) for (int i=0 ilt65 ++i) mpidigits(false) mpidigits(true)

20 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingближе к делу пример

bull Метрика время исполненияndash time java -server pidigits 1000

bull ldquoПрогреемrdquo

pidigitsjava public static void main(String[] args) pidigits m = new pidigits(IntegerparseInt(args[0])) for (int i=0 ilt19 ++i) mpidigits(false) mpidigits(true)

pidigitsjavasteady public static void main(String[] args) pidigits m = new pidigits(IntegerparseInt(args[0])) for (int i=0 ilt65 ++i) mpidigits(false) mpidigits(true)

21 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingв век многоядерных систем

bull Обычная платформаndash 2x2 Intel i5 26 Ghz Ubuntu 1010 i686 JDK 6u25

bull Три варианта экспериментаndash 1 экземпляр бенчмарка

bull по ldquoметодологии CLBGrdquo (+ корректный прогрев)

bull GMP будет использовать 1x4=4 потока

bull BI будет использовать 1x1=1 поток

ndash 4 экземпляра бенчмарка

bull чтобы утилизировать все ядра = снормировать на систему

bull GMP будет использовать 4х4=16 потоков

bull BI будет использовать 4x1=4 потока

ndash 16 потоков

bull ради одинаковой нагрузки на OS = снормировать на систему+OS

bull GMP будет использовать 4х4=16 потоков

bull BI будет работать в 16x1=16 потоков

bull Какой из них наиболее релевантен

22 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingа вот и данные

1 экземпляр 4 экземпляра 16 потоков

ldquoGMPrdquo

884[869 899]

1328 [1286 1371]

1328 [1286 1371]

ldquoBigIntegerrdquo

621 [619 624]

1346 [1335 1356]

1434 [1421 1446]

bull Метрика операции в секундуndash 20 итерацийndash [a b] ndash доверительный интервал на 95

24 copy JavaTechDays 2011 Oracle Corporation

Java 7 Java 8что ожидать в области производительности

bull Java 7ndash invokedynamicndash NIO2ndash Concurrency and Collection updates (ForkJoin)ndash XRender pipeline for Java2D (client)

bull Java 8 (или позже)ndash Модульностьndash -выражения (замыкания)ndash Collection updates (filter map reduce)

25 copy JavaTechDays 2011 Oracle Corporation

bull Мешает ли улучшать производительность JVMndash Да поэтому иногда расширяемся

bull invokedynamicbull Модульность

bull Стоит ли расширяться по первому требованию ndash Нет развитие JVMJIT реализация новых методов оптимизации

позволяет получить бОльший выигрышbull Вложенные классыbull Reflection

Обратная совместимость

26 copy JavaTechDays 2011 Oracle Corporation

Solaris

Лучшая ОС для Javaугадайте какая

bull Высокопроизводительный TCPIP стекndash low-latencyndash up to 50 faster

bull DTracendash мониторинг

bull NUMAndash MPO Memory Placement Optimization

bull Large Pagesndash Автоматическая аллокацияndash Разные размеры

27 copy JavaTechDays 2011 Oracle Corporation

hellip and beyondнастройка параметров JVM

bull Что настраиватьndash httpblogssuncomwattresourcejvm-options-listhtml

ndash httpwwworaclecomtechnetworkjavajavasetechvmoptions-jsp-140102html

bull JVM сама подбирает оптимальные параметры своей работыndash Server vs Client ndash Large pages (Solaris)ndash CompressedOops (64-bit VM)

bull Так что же настраиватьndash GCHeap tuningndash -XX+UseNUMA (Solaris Linux)ndash -XX+UseLargePages (Linux Windows)

bull httpwwworaclecomtechnetworkjavajavasetechlargememory-jsp-137182html

bull Не забытьndash Использовать последнюю версию JDK

29 copy JavaTechDays 2011 Oracle Corporation

Concurrencyэлементная база

bull OS Threadingndash мьютексы

bull mutex_lock()mutex_unlock()ndash conditional waits

bull cond_wait()cond_signal()bull WaitForSingleObject

bull Compare-and-Swap (CAS)ndash CAS(x1 x2 x3) = if (x1 == x2) x1 = x3 ndash атомарная операция поддерживаемая в ldquoжелезеrdquo из нескольких

одновременных CASов успешно завершается только одинndash Миф локальный CAS блокирует шину и стоит больше на

многопроцессорных системах ndash Факт глобальный CAS требует трафика на шине

httpblogssuncomdaveentrybiased_locking_in_hotspot

30 copy JavaTechDays 2011 Oracle Corporation

Concurrencyatomics

bull javautilconcurrentAtomicndash обеспечивают атомарные операции над примитивами и указателямиndash альтернатива synchronized или Lockи

bull Трюк в использовании CASаndash Изменение состояния атомика делается при помощи одного CASаndash Чтение состояния не требует CASа

public final int incrementAndGet() for () int current = get() int next = current + 1 if (compareAndSet(current next)) return next

mov ecxedxmov 0x8(ecx)eaxlea 0x8(ecx)edimov eaxecxinc ecxlock cmpxchg ecx(edi)mov $0x0ebxjne [ok]mov $0x1ebxtest ebxebxje [ok]

31 copy JavaTechDays 2011 Oracle Corporation

Concurrencyvolatile

bull Volatile определяет порядок чтения-записей в полеndash Точная семантика определена в Java Memory Model

bull НЕ обеспечивает атомарностиndash Реализуется расстановкой барьеров

bull Какие из них вставятся в код зависит от Hardware Memory Modelbull Эффект барьера зависит от HMM

PUSHL EBPSUB ESP8MOV EBX[ECX + 12]MEMBAR-acquireMEMBAR-releaseINC EBXMOV [ECX + 12]EBXMEMBAR-volatileLOCK ADDL [ESP + 0] 0ADD ESP8POPL EBPTEST PollPageEAXRET

push ebpsub $0x8espmov 0xc(ecx)ebxinc ebxmov ebx0xc(ecx)lock addl $0x0(esp)add $0x8esppop ebptest eax0xb779c000ret

httpgoswegoedudljmmcookbookhtml

32 copy JavaTechDays 2011 Oracle Corporation

Concurrencyvolatile-счётчик

public class VolatileTest

private int counter = 0 private volatile int volatileCounter = 0

GenerateMicroBenchmark public void testOrdinary() counter++

GenerateMicroBenchmark public void testVolatile() volatileCounter++

33 copy JavaTechDays 2011 Oracle Corporation

Concurrencyбесконфликтный volatile-счётчик

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

500000

1000000

1500000

2000000

2500000

3000000

3500000

Thread-local counter performance

ordinary volatile

Threads

op

ss

ec

34 copy JavaTechDays 2011 Oracle Corporation

Concurrencyконфликтный volatile-счётчик

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

100000

200000

300000

400000

500000

600000

700000

800000

900000

Global counter performance

ordinary volatile

Threads

op

ss

ec

35 copy JavaTechDays 2011 Oracle Corporation

Concurrencyintrinsic synchronization

bull synchronized(object) bull 4 состояния

ndash Initbull Начальное ldquoнеопределённоеrdquo состояние

ndash Biasedbull Захватывается одним ldquoвладеющимrdquo потоком нет конфликтовbull Захват владельцем проверка на threadIDbull Захват не-владельцем переход либо в Biased либо в Thin

ndash Thinbull Захватывается несколькими потоками но конфликтов нетbull Захват CASbull Конфликтный захват переход в Fat

ndash Fatbull Захватывается несколькими потоками конфликт на блокировкеbull Вызов примитива синхронизации из ОС

36 copy JavaTechDays 2011 Oracle Corporation

ConcurrencyjavautilconcurrentLock

bull Построены на базе jucAbstractQueueSynchronizerndash Использует атомики

bull CAS

ndash Использует Unsafepark()unpark()

bull интринзики для cond_wait()cond_signal()WaitForSingleObject()

bull ReentrantLockndash По семантике эквивалентен synchronized

bull Рекурсивный захват проверка на threadID

bull Ставит потоки во внутреннюю очередь и делает park()

ndash Non-Fair (default)

bull Не гарантирует отсутствие starvation

bull Barging FIFO (CAS)

bull Лучшая производительность

ndash Fair

bull Гарантирует отсутствие starvation

bull FIFO

bull Честность в обмен на производительностьhttpgeecsoswegoedudlpapersaqspdf

37 copy JavaTechDays 2011 Oracle Corporation

Concurrencyатомарный счётчик

private AtomicInteger atomic = new AtomicInteger() private ReentrantLock lock = new ReentrantLock() private final Object intrinsicLock = new Object() private int primCounter = 0

GenerateMicroBenchmark public void testAtomicInteger() atomicincrementAndGet()

GenerateMicroBenchmark public void testReentrantLock() locklock() primCounter++ lockunlock()

GenerateMicroBenchmark public void testIntrinsicLock() synchronized (intrinsicLock) primCounter++

38 copy JavaTechDays 2011 Oracle Corporation

Concurrencyатомарный счётчик

0 16 32 48 64 80 96 112 128

1000

10000

100000

Atomic Counter Performance

Intrinsic AtomicInteger ReentrantLock

Threads

ops

sec

8x8 CPUs Solaris 6u25

39 copy JavaTechDays 2011 Oracle Corporation

ConcurrencyReentrantLock vs synchronized

bull Семантика одинаковаndash Требования к видимости памяти

ndash Рекурсивный

bull Плюсы jucRLndash Очередь потоков держится на стороне JVM

bull опционально FIFO-политика при захвате-освобождении

bull позволяет быть ldquoчестнымrdquo на любой платформе

ndash Barging FIFO policy

bull lock() может быть сразу удовлетворён даже если в очереди есть потоки

bull сильно улучшает производительность при конфликте блокировок

ndash Допускается несколько Condition

bull Минусы jucRLndash Нет scopeов требуется ручной unlock() через finally

bull Должно быть проще с ARM в JDK7

40 copy JavaTechDays 2011 Oracle Corporation

Concurrencyбесконфликтный захват

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

10000

20000

30000

40000

50000

60000

70000

80000

90000

100000

110000

120000

130000

140000

150000

Uncontended Lock Performance

intrinsic jucReentrantL (non-fair) jucReentrantL (fair)

Threads

op

sse

c

41 copy JavaTechDays 2011 Oracle Corporation

Concurrencyконфликтный захват

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

500

1000

1500

2000

2500

3000

3500

4000

4500

Contended Lock Performance

intrinsic jucReentrantL (non-fair) jucReentrantL (fair)

Threads

op

sse

c

43 copy 2011 JavaTechDays Oracle Corporation

bull hellip естьbull hellip работаетbull hellip работает хорошоbull hellip знает о железе всё

ndash Количество и тип CPUndash Поддерживаемые инcтрукции (SSEx AVX VIS)ndash Топологию памяти (в тч размеры кэшей и их характеристики)

bull hellip знает о приложении много всегоndash Иерархию загруженных классовndash Актуальную статистику создания объектовndash Горячий кодndash Какие ветвления исполнялисьndash Какие значения использовалисьndash Многое другое

bull hellip не боится использовать эти знания для компиляции

JITфакты

44 copy 2011 JavaTechDays Oracle Corporation

JITоптимизации

46 copy 2011 JavaTechDays Oracle Corporation

JITкак писать код

bull Используйте стандартные библиотекиndash Зачем писать собственный стандартный контейнер

bull Используйте высокоуровневый API ndash javautilndash javautilconcurrentndash NIO NIO2ndash вообще библиотеки

bull Код должен правильным и понятнымndash Сначала правильноndash Потом алгоритмически ldquoбыстроrdquondash Код не должен быть JIT-oriented

bull Правильно используйте возможности языкаndash EPIC FAIL штатная передача управления exceptionамиndash FAIL Возврат ldquoисключенияrdquo через return ltкод_ошибкиgtndash FAIL int вместо Enum или boolean

47 copy 2011 JavaTechDays Oracle Corporation

Как получить ассемблерный код метода

ndash Обычным дебаггером )

ndash JVMTI

ndash -XX+PrintAssemblybull httpwikissuncomdisplayHotSpotInternalsPrintAssembly

JITдля любопытных

54 copy JavaTechDays 2011 Oracle Corporation

StartupEclipse

bull Типичная конфигурацияndash 2x2 Intel i5 26 Ghz Ubuntu 1010 i686 JDK 6u25ndash Eclipse JDT (Galileo)

bull Типичные метрикиndash 6000 загруженных классовndash 1000 методов скомпилированоndash 512 Mb зарезервированного пространства в кучеndash 25 Mb кучи использовано после стартапа

bull Известные ldquoпроблемыrdquondash Загрузка и верификация классовndash JIT-компиляция

55 copy JavaTechDays 2011 Oracle Corporation

StartupEclipse

bull Метрика секунд на запуск-завершениеndash Файловые кеши прогреты практически нулевой дисковый IO

default CDS CDS + no-verify

абсолютное время

583 [574 592]

481[473 484]

461[456 474]

загрузка классов

501[491 511]

339[312 366]

301[294 308]

компиляция 051[043 059]

051[044 058]

051[042 060]

56 copy JavaTechDays 2011 Oracle Corporation

Startupдлинные приложения

bull Важно только для коротких приложенийndash Чем дольше работает приложение тем меньше удельные затраты на

загрузку классов и компиляцию

bull Пример 8 часа работает IntelliJ IDEA 10xndash 26600 классов загруженоndash 5315 методов скомпилировано

bull Загрузка классовndash Всего потрачено 202 с ~07 общего времениndash 10 мсек на класс

bull Компиляцияndash Всего потрачено 112 с ~003 общего времениndash 20 мсек на метод

57 copy JavaTechDays 2011 Oracle Corporation

Whats Next

bull Послушать ещёndash JavaOne Moscow (апрель 2011)

bull Проблема со слайдамиndash Найдите нас на конференцииndash Напишите нам письмо

bull Проблема с JDKndash httpopenjdkjavanetndash Задайте вопрос в OpenJDKndash а лучше сделайте патч и дайте его в OpenJDK на review

58 copy JavaTechDays 2011 Oracle Corporation

QA

Page 7: Java Platform Performance BoF - Aleksey Shipilëv · – 2x2 Intel i5 2.6 Ghz, Ubuntu 10.10 i686, JDK 6u25 • Три варианта эксперимента: – 1 экземпляр

11 copy JavaTechDays 2011 Oracle Corporation

Performance Engineeringtools tools tools again more tools

bull VisualVM ndash httpvisualvmdevjavanet

bull JRockit Mission Controlndash httpwwworaclecomtechnetworkmiddlewarejrockitmission-controlindexhtml

bull Sun Studio Analyzerndash httpwwworaclecomtechnetworkserver-storagesolarisstudiooverviewindexhtml

bull NetBeans Profilerndash httpwwwnetbeansorg

bull DTracendash httpwwworaclecomtechnetworksystemsdtracedtraceindexhtml

bull Ещё могут быть полезныndash JProbendash OptimizeItndash YourKit

13 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingна чём измерять производительность

ldquoмикроrdquoбенчмарки

синтетические бенчмарки

авто-сценарии реальных приложений

реальные приложения

релевантность плохая средняя хорошая отличная

расходы на разработку и поддержку

низкие средние средние высокие

расходы на запуск

низкие низкие средние высокие

сложность интерпретации результатов

очень сложно

средняя достаточно просто

сложно

14 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingнаша стратегия

bull Сделать реальные приложения быстрееndash Но слишком сложно поддерживать и запускатьndash Поэтому

bull Сфокусироваться на синтетических бенчмарках и авто-сценарияхndash SPECjbb SPECjvm SPECjAppServer SPECjEnterprisendash Glassfish Weblogic NetBeans и тпndash Большие in-house нагрузки

bull Пользоваться микробенчмарками с опаскойndash Иногда от них никуда не детьсяndash Очень легко написать очень легко запуститьndash Очень легко ldquoвыстрелить себе в ногуrdquondash что чуть ли не каждую неделю демонстрируется в профильных

блогах

15 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingитак вы решили написать свой бенчмарк

bull Опасайтесь типичных ошибокbull Дизайн эксперимента

ndash Что хотим измеритьndash Каким способом будем измерять

bull Реализация экспериментаndash Отсутствие прогрева ldquoмёртвый кодrdquo etcndash Многопоточность утилизацияndash Контроль переменных результат воспроизводитсяndash Контроль переменных результат вообще зависит от входов

bull Интерпретация результатовndash Что в итоге измерилиndash Значим ли результат

bull 1000 opssec против 1050 opssec ndash прирост или нет

16 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingближе к делу пример

bull Computer Language Benchmark Gamendash httpshootoutaliothdebianorgndash Самый известный полигон для расстрела невинных ног

bull Тест ldquoPiDigitsrdquondash Вычислить первые N цифр в десятичном разложении πndash Вычисляется приближение π специальным рядом

bull Требуется arbitrary precision для представления рациональных членов ряда

ndash Потенциально параллелизуемаndash Две версии Java-теста

bull Текущая использует GNU MP внутренне параллельна 240 строк кода Java + нативные врапперы + GMP

bull Предыдущая использует BigInteger не параллельна 130 строк кода plain Java

17 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingближе к делу пример

bull Computer Language Benchmark Gamendash httpshootoutaliothdebianorgndash Самый известный полигон для расстрела невинных ног

bull Тест ldquoPiDigitsrdquondash Вычислить первые N цифр в десятичном разложении πndash Вычисляется приближение π специальным рядом

bull Требуется arbitrary precision для представления рациональных членов ряда

ndash Потенциально параллелизуемаndash Две версии Java-теста

bull Текущая использует GNU MP внутренне параллельна 240 строк кода Java + нативные врапперы + GMP

bull Предыдущая использует BigInteger не параллельна 130 строк кода plain Java

18 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingближе к делу пример

bull Метрика время исполненияndash time java -server pidigits 1000

bull ldquoПрогреемrdquo

pidigitsjavasteady public static void main(String[] args) pidigits m = new pidigits(IntegerparseInt(args[0])) for (int i=0 ilt65 ++i) mpidigits(false) mpidigits(true)

19 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingближе к делу пример

bull Метрика время исполненияndash time java -server pidigits 1000

bull ldquoПрогреемrdquo

pidigitsjavasteady public static void main(String[] args) pidigits m = new pidigits(IntegerparseInt(args[0])) for (int i=0 ilt65 ++i) mpidigits(false) mpidigits(true)

20 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingближе к делу пример

bull Метрика время исполненияndash time java -server pidigits 1000

bull ldquoПрогреемrdquo

pidigitsjava public static void main(String[] args) pidigits m = new pidigits(IntegerparseInt(args[0])) for (int i=0 ilt19 ++i) mpidigits(false) mpidigits(true)

pidigitsjavasteady public static void main(String[] args) pidigits m = new pidigits(IntegerparseInt(args[0])) for (int i=0 ilt65 ++i) mpidigits(false) mpidigits(true)

21 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingв век многоядерных систем

bull Обычная платформаndash 2x2 Intel i5 26 Ghz Ubuntu 1010 i686 JDK 6u25

bull Три варианта экспериментаndash 1 экземпляр бенчмарка

bull по ldquoметодологии CLBGrdquo (+ корректный прогрев)

bull GMP будет использовать 1x4=4 потока

bull BI будет использовать 1x1=1 поток

ndash 4 экземпляра бенчмарка

bull чтобы утилизировать все ядра = снормировать на систему

bull GMP будет использовать 4х4=16 потоков

bull BI будет использовать 4x1=4 потока

ndash 16 потоков

bull ради одинаковой нагрузки на OS = снормировать на систему+OS

bull GMP будет использовать 4х4=16 потоков

bull BI будет работать в 16x1=16 потоков

bull Какой из них наиболее релевантен

22 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingа вот и данные

1 экземпляр 4 экземпляра 16 потоков

ldquoGMPrdquo

884[869 899]

1328 [1286 1371]

1328 [1286 1371]

ldquoBigIntegerrdquo

621 [619 624]

1346 [1335 1356]

1434 [1421 1446]

bull Метрика операции в секундуndash 20 итерацийndash [a b] ndash доверительный интервал на 95

24 copy JavaTechDays 2011 Oracle Corporation

Java 7 Java 8что ожидать в области производительности

bull Java 7ndash invokedynamicndash NIO2ndash Concurrency and Collection updates (ForkJoin)ndash XRender pipeline for Java2D (client)

bull Java 8 (или позже)ndash Модульностьndash -выражения (замыкания)ndash Collection updates (filter map reduce)

25 copy JavaTechDays 2011 Oracle Corporation

bull Мешает ли улучшать производительность JVMndash Да поэтому иногда расширяемся

bull invokedynamicbull Модульность

bull Стоит ли расширяться по первому требованию ndash Нет развитие JVMJIT реализация новых методов оптимизации

позволяет получить бОльший выигрышbull Вложенные классыbull Reflection

Обратная совместимость

26 copy JavaTechDays 2011 Oracle Corporation

Solaris

Лучшая ОС для Javaугадайте какая

bull Высокопроизводительный TCPIP стекndash low-latencyndash up to 50 faster

bull DTracendash мониторинг

bull NUMAndash MPO Memory Placement Optimization

bull Large Pagesndash Автоматическая аллокацияndash Разные размеры

27 copy JavaTechDays 2011 Oracle Corporation

hellip and beyondнастройка параметров JVM

bull Что настраиватьndash httpblogssuncomwattresourcejvm-options-listhtml

ndash httpwwworaclecomtechnetworkjavajavasetechvmoptions-jsp-140102html

bull JVM сама подбирает оптимальные параметры своей работыndash Server vs Client ndash Large pages (Solaris)ndash CompressedOops (64-bit VM)

bull Так что же настраиватьndash GCHeap tuningndash -XX+UseNUMA (Solaris Linux)ndash -XX+UseLargePages (Linux Windows)

bull httpwwworaclecomtechnetworkjavajavasetechlargememory-jsp-137182html

bull Не забытьndash Использовать последнюю версию JDK

29 copy JavaTechDays 2011 Oracle Corporation

Concurrencyэлементная база

bull OS Threadingndash мьютексы

bull mutex_lock()mutex_unlock()ndash conditional waits

bull cond_wait()cond_signal()bull WaitForSingleObject

bull Compare-and-Swap (CAS)ndash CAS(x1 x2 x3) = if (x1 == x2) x1 = x3 ndash атомарная операция поддерживаемая в ldquoжелезеrdquo из нескольких

одновременных CASов успешно завершается только одинndash Миф локальный CAS блокирует шину и стоит больше на

многопроцессорных системах ndash Факт глобальный CAS требует трафика на шине

httpblogssuncomdaveentrybiased_locking_in_hotspot

30 copy JavaTechDays 2011 Oracle Corporation

Concurrencyatomics

bull javautilconcurrentAtomicndash обеспечивают атомарные операции над примитивами и указателямиndash альтернатива synchronized или Lockи

bull Трюк в использовании CASаndash Изменение состояния атомика делается при помощи одного CASаndash Чтение состояния не требует CASа

public final int incrementAndGet() for () int current = get() int next = current + 1 if (compareAndSet(current next)) return next

mov ecxedxmov 0x8(ecx)eaxlea 0x8(ecx)edimov eaxecxinc ecxlock cmpxchg ecx(edi)mov $0x0ebxjne [ok]mov $0x1ebxtest ebxebxje [ok]

31 copy JavaTechDays 2011 Oracle Corporation

Concurrencyvolatile

bull Volatile определяет порядок чтения-записей в полеndash Точная семантика определена в Java Memory Model

bull НЕ обеспечивает атомарностиndash Реализуется расстановкой барьеров

bull Какие из них вставятся в код зависит от Hardware Memory Modelbull Эффект барьера зависит от HMM

PUSHL EBPSUB ESP8MOV EBX[ECX + 12]MEMBAR-acquireMEMBAR-releaseINC EBXMOV [ECX + 12]EBXMEMBAR-volatileLOCK ADDL [ESP + 0] 0ADD ESP8POPL EBPTEST PollPageEAXRET

push ebpsub $0x8espmov 0xc(ecx)ebxinc ebxmov ebx0xc(ecx)lock addl $0x0(esp)add $0x8esppop ebptest eax0xb779c000ret

httpgoswegoedudljmmcookbookhtml

32 copy JavaTechDays 2011 Oracle Corporation

Concurrencyvolatile-счётчик

public class VolatileTest

private int counter = 0 private volatile int volatileCounter = 0

GenerateMicroBenchmark public void testOrdinary() counter++

GenerateMicroBenchmark public void testVolatile() volatileCounter++

33 copy JavaTechDays 2011 Oracle Corporation

Concurrencyбесконфликтный volatile-счётчик

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

500000

1000000

1500000

2000000

2500000

3000000

3500000

Thread-local counter performance

ordinary volatile

Threads

op

ss

ec

34 copy JavaTechDays 2011 Oracle Corporation

Concurrencyконфликтный volatile-счётчик

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

100000

200000

300000

400000

500000

600000

700000

800000

900000

Global counter performance

ordinary volatile

Threads

op

ss

ec

35 copy JavaTechDays 2011 Oracle Corporation

Concurrencyintrinsic synchronization

bull synchronized(object) bull 4 состояния

ndash Initbull Начальное ldquoнеопределённоеrdquo состояние

ndash Biasedbull Захватывается одним ldquoвладеющимrdquo потоком нет конфликтовbull Захват владельцем проверка на threadIDbull Захват не-владельцем переход либо в Biased либо в Thin

ndash Thinbull Захватывается несколькими потоками но конфликтов нетbull Захват CASbull Конфликтный захват переход в Fat

ndash Fatbull Захватывается несколькими потоками конфликт на блокировкеbull Вызов примитива синхронизации из ОС

36 copy JavaTechDays 2011 Oracle Corporation

ConcurrencyjavautilconcurrentLock

bull Построены на базе jucAbstractQueueSynchronizerndash Использует атомики

bull CAS

ndash Использует Unsafepark()unpark()

bull интринзики для cond_wait()cond_signal()WaitForSingleObject()

bull ReentrantLockndash По семантике эквивалентен synchronized

bull Рекурсивный захват проверка на threadID

bull Ставит потоки во внутреннюю очередь и делает park()

ndash Non-Fair (default)

bull Не гарантирует отсутствие starvation

bull Barging FIFO (CAS)

bull Лучшая производительность

ndash Fair

bull Гарантирует отсутствие starvation

bull FIFO

bull Честность в обмен на производительностьhttpgeecsoswegoedudlpapersaqspdf

37 copy JavaTechDays 2011 Oracle Corporation

Concurrencyатомарный счётчик

private AtomicInteger atomic = new AtomicInteger() private ReentrantLock lock = new ReentrantLock() private final Object intrinsicLock = new Object() private int primCounter = 0

GenerateMicroBenchmark public void testAtomicInteger() atomicincrementAndGet()

GenerateMicroBenchmark public void testReentrantLock() locklock() primCounter++ lockunlock()

GenerateMicroBenchmark public void testIntrinsicLock() synchronized (intrinsicLock) primCounter++

38 copy JavaTechDays 2011 Oracle Corporation

Concurrencyатомарный счётчик

0 16 32 48 64 80 96 112 128

1000

10000

100000

Atomic Counter Performance

Intrinsic AtomicInteger ReentrantLock

Threads

ops

sec

8x8 CPUs Solaris 6u25

39 copy JavaTechDays 2011 Oracle Corporation

ConcurrencyReentrantLock vs synchronized

bull Семантика одинаковаndash Требования к видимости памяти

ndash Рекурсивный

bull Плюсы jucRLndash Очередь потоков держится на стороне JVM

bull опционально FIFO-политика при захвате-освобождении

bull позволяет быть ldquoчестнымrdquo на любой платформе

ndash Barging FIFO policy

bull lock() может быть сразу удовлетворён даже если в очереди есть потоки

bull сильно улучшает производительность при конфликте блокировок

ndash Допускается несколько Condition

bull Минусы jucRLndash Нет scopeов требуется ручной unlock() через finally

bull Должно быть проще с ARM в JDK7

40 copy JavaTechDays 2011 Oracle Corporation

Concurrencyбесконфликтный захват

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

10000

20000

30000

40000

50000

60000

70000

80000

90000

100000

110000

120000

130000

140000

150000

Uncontended Lock Performance

intrinsic jucReentrantL (non-fair) jucReentrantL (fair)

Threads

op

sse

c

41 copy JavaTechDays 2011 Oracle Corporation

Concurrencyконфликтный захват

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

500

1000

1500

2000

2500

3000

3500

4000

4500

Contended Lock Performance

intrinsic jucReentrantL (non-fair) jucReentrantL (fair)

Threads

op

sse

c

43 copy 2011 JavaTechDays Oracle Corporation

bull hellip естьbull hellip работаетbull hellip работает хорошоbull hellip знает о железе всё

ndash Количество и тип CPUndash Поддерживаемые инcтрукции (SSEx AVX VIS)ndash Топологию памяти (в тч размеры кэшей и их характеристики)

bull hellip знает о приложении много всегоndash Иерархию загруженных классовndash Актуальную статистику создания объектовndash Горячий кодndash Какие ветвления исполнялисьndash Какие значения использовалисьndash Многое другое

bull hellip не боится использовать эти знания для компиляции

JITфакты

44 copy 2011 JavaTechDays Oracle Corporation

JITоптимизации

46 copy 2011 JavaTechDays Oracle Corporation

JITкак писать код

bull Используйте стандартные библиотекиndash Зачем писать собственный стандартный контейнер

bull Используйте высокоуровневый API ndash javautilndash javautilconcurrentndash NIO NIO2ndash вообще библиотеки

bull Код должен правильным и понятнымndash Сначала правильноndash Потом алгоритмически ldquoбыстроrdquondash Код не должен быть JIT-oriented

bull Правильно используйте возможности языкаndash EPIC FAIL штатная передача управления exceptionамиndash FAIL Возврат ldquoисключенияrdquo через return ltкод_ошибкиgtndash FAIL int вместо Enum или boolean

47 copy 2011 JavaTechDays Oracle Corporation

Как получить ассемблерный код метода

ndash Обычным дебаггером )

ndash JVMTI

ndash -XX+PrintAssemblybull httpwikissuncomdisplayHotSpotInternalsPrintAssembly

JITдля любопытных

54 copy JavaTechDays 2011 Oracle Corporation

StartupEclipse

bull Типичная конфигурацияndash 2x2 Intel i5 26 Ghz Ubuntu 1010 i686 JDK 6u25ndash Eclipse JDT (Galileo)

bull Типичные метрикиndash 6000 загруженных классовndash 1000 методов скомпилированоndash 512 Mb зарезервированного пространства в кучеndash 25 Mb кучи использовано после стартапа

bull Известные ldquoпроблемыrdquondash Загрузка и верификация классовndash JIT-компиляция

55 copy JavaTechDays 2011 Oracle Corporation

StartupEclipse

bull Метрика секунд на запуск-завершениеndash Файловые кеши прогреты практически нулевой дисковый IO

default CDS CDS + no-verify

абсолютное время

583 [574 592]

481[473 484]

461[456 474]

загрузка классов

501[491 511]

339[312 366]

301[294 308]

компиляция 051[043 059]

051[044 058]

051[042 060]

56 copy JavaTechDays 2011 Oracle Corporation

Startupдлинные приложения

bull Важно только для коротких приложенийndash Чем дольше работает приложение тем меньше удельные затраты на

загрузку классов и компиляцию

bull Пример 8 часа работает IntelliJ IDEA 10xndash 26600 классов загруженоndash 5315 методов скомпилировано

bull Загрузка классовndash Всего потрачено 202 с ~07 общего времениndash 10 мсек на класс

bull Компиляцияndash Всего потрачено 112 с ~003 общего времениndash 20 мсек на метод

57 copy JavaTechDays 2011 Oracle Corporation

Whats Next

bull Послушать ещёndash JavaOne Moscow (апрель 2011)

bull Проблема со слайдамиndash Найдите нас на конференцииndash Напишите нам письмо

bull Проблема с JDKndash httpopenjdkjavanetndash Задайте вопрос в OpenJDKndash а лучше сделайте патч и дайте его в OpenJDK на review

58 copy JavaTechDays 2011 Oracle Corporation

QA

Page 8: Java Platform Performance BoF - Aleksey Shipilëv · – 2x2 Intel i5 2.6 Ghz, Ubuntu 10.10 i686, JDK 6u25 • Три варианта эксперимента: – 1 экземпляр

13 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingна чём измерять производительность

ldquoмикроrdquoбенчмарки

синтетические бенчмарки

авто-сценарии реальных приложений

реальные приложения

релевантность плохая средняя хорошая отличная

расходы на разработку и поддержку

низкие средние средние высокие

расходы на запуск

низкие низкие средние высокие

сложность интерпретации результатов

очень сложно

средняя достаточно просто

сложно

14 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingнаша стратегия

bull Сделать реальные приложения быстрееndash Но слишком сложно поддерживать и запускатьndash Поэтому

bull Сфокусироваться на синтетических бенчмарках и авто-сценарияхndash SPECjbb SPECjvm SPECjAppServer SPECjEnterprisendash Glassfish Weblogic NetBeans и тпndash Большие in-house нагрузки

bull Пользоваться микробенчмарками с опаскойndash Иногда от них никуда не детьсяndash Очень легко написать очень легко запуститьndash Очень легко ldquoвыстрелить себе в ногуrdquondash что чуть ли не каждую неделю демонстрируется в профильных

блогах

15 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingитак вы решили написать свой бенчмарк

bull Опасайтесь типичных ошибокbull Дизайн эксперимента

ndash Что хотим измеритьndash Каким способом будем измерять

bull Реализация экспериментаndash Отсутствие прогрева ldquoмёртвый кодrdquo etcndash Многопоточность утилизацияndash Контроль переменных результат воспроизводитсяndash Контроль переменных результат вообще зависит от входов

bull Интерпретация результатовndash Что в итоге измерилиndash Значим ли результат

bull 1000 opssec против 1050 opssec ndash прирост или нет

16 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingближе к делу пример

bull Computer Language Benchmark Gamendash httpshootoutaliothdebianorgndash Самый известный полигон для расстрела невинных ног

bull Тест ldquoPiDigitsrdquondash Вычислить первые N цифр в десятичном разложении πndash Вычисляется приближение π специальным рядом

bull Требуется arbitrary precision для представления рациональных членов ряда

ndash Потенциально параллелизуемаndash Две версии Java-теста

bull Текущая использует GNU MP внутренне параллельна 240 строк кода Java + нативные врапперы + GMP

bull Предыдущая использует BigInteger не параллельна 130 строк кода plain Java

17 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingближе к делу пример

bull Computer Language Benchmark Gamendash httpshootoutaliothdebianorgndash Самый известный полигон для расстрела невинных ног

bull Тест ldquoPiDigitsrdquondash Вычислить первые N цифр в десятичном разложении πndash Вычисляется приближение π специальным рядом

bull Требуется arbitrary precision для представления рациональных членов ряда

ndash Потенциально параллелизуемаndash Две версии Java-теста

bull Текущая использует GNU MP внутренне параллельна 240 строк кода Java + нативные врапперы + GMP

bull Предыдущая использует BigInteger не параллельна 130 строк кода plain Java

18 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingближе к делу пример

bull Метрика время исполненияndash time java -server pidigits 1000

bull ldquoПрогреемrdquo

pidigitsjavasteady public static void main(String[] args) pidigits m = new pidigits(IntegerparseInt(args[0])) for (int i=0 ilt65 ++i) mpidigits(false) mpidigits(true)

19 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingближе к делу пример

bull Метрика время исполненияndash time java -server pidigits 1000

bull ldquoПрогреемrdquo

pidigitsjavasteady public static void main(String[] args) pidigits m = new pidigits(IntegerparseInt(args[0])) for (int i=0 ilt65 ++i) mpidigits(false) mpidigits(true)

20 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingближе к делу пример

bull Метрика время исполненияndash time java -server pidigits 1000

bull ldquoПрогреемrdquo

pidigitsjava public static void main(String[] args) pidigits m = new pidigits(IntegerparseInt(args[0])) for (int i=0 ilt19 ++i) mpidigits(false) mpidigits(true)

pidigitsjavasteady public static void main(String[] args) pidigits m = new pidigits(IntegerparseInt(args[0])) for (int i=0 ilt65 ++i) mpidigits(false) mpidigits(true)

21 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingв век многоядерных систем

bull Обычная платформаndash 2x2 Intel i5 26 Ghz Ubuntu 1010 i686 JDK 6u25

bull Три варианта экспериментаndash 1 экземпляр бенчмарка

bull по ldquoметодологии CLBGrdquo (+ корректный прогрев)

bull GMP будет использовать 1x4=4 потока

bull BI будет использовать 1x1=1 поток

ndash 4 экземпляра бенчмарка

bull чтобы утилизировать все ядра = снормировать на систему

bull GMP будет использовать 4х4=16 потоков

bull BI будет использовать 4x1=4 потока

ndash 16 потоков

bull ради одинаковой нагрузки на OS = снормировать на систему+OS

bull GMP будет использовать 4х4=16 потоков

bull BI будет работать в 16x1=16 потоков

bull Какой из них наиболее релевантен

22 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingа вот и данные

1 экземпляр 4 экземпляра 16 потоков

ldquoGMPrdquo

884[869 899]

1328 [1286 1371]

1328 [1286 1371]

ldquoBigIntegerrdquo

621 [619 624]

1346 [1335 1356]

1434 [1421 1446]

bull Метрика операции в секундуndash 20 итерацийndash [a b] ndash доверительный интервал на 95

24 copy JavaTechDays 2011 Oracle Corporation

Java 7 Java 8что ожидать в области производительности

bull Java 7ndash invokedynamicndash NIO2ndash Concurrency and Collection updates (ForkJoin)ndash XRender pipeline for Java2D (client)

bull Java 8 (или позже)ndash Модульностьndash -выражения (замыкания)ndash Collection updates (filter map reduce)

25 copy JavaTechDays 2011 Oracle Corporation

bull Мешает ли улучшать производительность JVMndash Да поэтому иногда расширяемся

bull invokedynamicbull Модульность

bull Стоит ли расширяться по первому требованию ndash Нет развитие JVMJIT реализация новых методов оптимизации

позволяет получить бОльший выигрышbull Вложенные классыbull Reflection

Обратная совместимость

26 copy JavaTechDays 2011 Oracle Corporation

Solaris

Лучшая ОС для Javaугадайте какая

bull Высокопроизводительный TCPIP стекndash low-latencyndash up to 50 faster

bull DTracendash мониторинг

bull NUMAndash MPO Memory Placement Optimization

bull Large Pagesndash Автоматическая аллокацияndash Разные размеры

27 copy JavaTechDays 2011 Oracle Corporation

hellip and beyondнастройка параметров JVM

bull Что настраиватьndash httpblogssuncomwattresourcejvm-options-listhtml

ndash httpwwworaclecomtechnetworkjavajavasetechvmoptions-jsp-140102html

bull JVM сама подбирает оптимальные параметры своей работыndash Server vs Client ndash Large pages (Solaris)ndash CompressedOops (64-bit VM)

bull Так что же настраиватьndash GCHeap tuningndash -XX+UseNUMA (Solaris Linux)ndash -XX+UseLargePages (Linux Windows)

bull httpwwworaclecomtechnetworkjavajavasetechlargememory-jsp-137182html

bull Не забытьndash Использовать последнюю версию JDK

29 copy JavaTechDays 2011 Oracle Corporation

Concurrencyэлементная база

bull OS Threadingndash мьютексы

bull mutex_lock()mutex_unlock()ndash conditional waits

bull cond_wait()cond_signal()bull WaitForSingleObject

bull Compare-and-Swap (CAS)ndash CAS(x1 x2 x3) = if (x1 == x2) x1 = x3 ndash атомарная операция поддерживаемая в ldquoжелезеrdquo из нескольких

одновременных CASов успешно завершается только одинndash Миф локальный CAS блокирует шину и стоит больше на

многопроцессорных системах ndash Факт глобальный CAS требует трафика на шине

httpblogssuncomdaveentrybiased_locking_in_hotspot

30 copy JavaTechDays 2011 Oracle Corporation

Concurrencyatomics

bull javautilconcurrentAtomicndash обеспечивают атомарные операции над примитивами и указателямиndash альтернатива synchronized или Lockи

bull Трюк в использовании CASаndash Изменение состояния атомика делается при помощи одного CASаndash Чтение состояния не требует CASа

public final int incrementAndGet() for () int current = get() int next = current + 1 if (compareAndSet(current next)) return next

mov ecxedxmov 0x8(ecx)eaxlea 0x8(ecx)edimov eaxecxinc ecxlock cmpxchg ecx(edi)mov $0x0ebxjne [ok]mov $0x1ebxtest ebxebxje [ok]

31 copy JavaTechDays 2011 Oracle Corporation

Concurrencyvolatile

bull Volatile определяет порядок чтения-записей в полеndash Точная семантика определена в Java Memory Model

bull НЕ обеспечивает атомарностиndash Реализуется расстановкой барьеров

bull Какие из них вставятся в код зависит от Hardware Memory Modelbull Эффект барьера зависит от HMM

PUSHL EBPSUB ESP8MOV EBX[ECX + 12]MEMBAR-acquireMEMBAR-releaseINC EBXMOV [ECX + 12]EBXMEMBAR-volatileLOCK ADDL [ESP + 0] 0ADD ESP8POPL EBPTEST PollPageEAXRET

push ebpsub $0x8espmov 0xc(ecx)ebxinc ebxmov ebx0xc(ecx)lock addl $0x0(esp)add $0x8esppop ebptest eax0xb779c000ret

httpgoswegoedudljmmcookbookhtml

32 copy JavaTechDays 2011 Oracle Corporation

Concurrencyvolatile-счётчик

public class VolatileTest

private int counter = 0 private volatile int volatileCounter = 0

GenerateMicroBenchmark public void testOrdinary() counter++

GenerateMicroBenchmark public void testVolatile() volatileCounter++

33 copy JavaTechDays 2011 Oracle Corporation

Concurrencyбесконфликтный volatile-счётчик

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

500000

1000000

1500000

2000000

2500000

3000000

3500000

Thread-local counter performance

ordinary volatile

Threads

op

ss

ec

34 copy JavaTechDays 2011 Oracle Corporation

Concurrencyконфликтный volatile-счётчик

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

100000

200000

300000

400000

500000

600000

700000

800000

900000

Global counter performance

ordinary volatile

Threads

op

ss

ec

35 copy JavaTechDays 2011 Oracle Corporation

Concurrencyintrinsic synchronization

bull synchronized(object) bull 4 состояния

ndash Initbull Начальное ldquoнеопределённоеrdquo состояние

ndash Biasedbull Захватывается одним ldquoвладеющимrdquo потоком нет конфликтовbull Захват владельцем проверка на threadIDbull Захват не-владельцем переход либо в Biased либо в Thin

ndash Thinbull Захватывается несколькими потоками но конфликтов нетbull Захват CASbull Конфликтный захват переход в Fat

ndash Fatbull Захватывается несколькими потоками конфликт на блокировкеbull Вызов примитива синхронизации из ОС

36 copy JavaTechDays 2011 Oracle Corporation

ConcurrencyjavautilconcurrentLock

bull Построены на базе jucAbstractQueueSynchronizerndash Использует атомики

bull CAS

ndash Использует Unsafepark()unpark()

bull интринзики для cond_wait()cond_signal()WaitForSingleObject()

bull ReentrantLockndash По семантике эквивалентен synchronized

bull Рекурсивный захват проверка на threadID

bull Ставит потоки во внутреннюю очередь и делает park()

ndash Non-Fair (default)

bull Не гарантирует отсутствие starvation

bull Barging FIFO (CAS)

bull Лучшая производительность

ndash Fair

bull Гарантирует отсутствие starvation

bull FIFO

bull Честность в обмен на производительностьhttpgeecsoswegoedudlpapersaqspdf

37 copy JavaTechDays 2011 Oracle Corporation

Concurrencyатомарный счётчик

private AtomicInteger atomic = new AtomicInteger() private ReentrantLock lock = new ReentrantLock() private final Object intrinsicLock = new Object() private int primCounter = 0

GenerateMicroBenchmark public void testAtomicInteger() atomicincrementAndGet()

GenerateMicroBenchmark public void testReentrantLock() locklock() primCounter++ lockunlock()

GenerateMicroBenchmark public void testIntrinsicLock() synchronized (intrinsicLock) primCounter++

38 copy JavaTechDays 2011 Oracle Corporation

Concurrencyатомарный счётчик

0 16 32 48 64 80 96 112 128

1000

10000

100000

Atomic Counter Performance

Intrinsic AtomicInteger ReentrantLock

Threads

ops

sec

8x8 CPUs Solaris 6u25

39 copy JavaTechDays 2011 Oracle Corporation

ConcurrencyReentrantLock vs synchronized

bull Семантика одинаковаndash Требования к видимости памяти

ndash Рекурсивный

bull Плюсы jucRLndash Очередь потоков держится на стороне JVM

bull опционально FIFO-политика при захвате-освобождении

bull позволяет быть ldquoчестнымrdquo на любой платформе

ndash Barging FIFO policy

bull lock() может быть сразу удовлетворён даже если в очереди есть потоки

bull сильно улучшает производительность при конфликте блокировок

ndash Допускается несколько Condition

bull Минусы jucRLndash Нет scopeов требуется ручной unlock() через finally

bull Должно быть проще с ARM в JDK7

40 copy JavaTechDays 2011 Oracle Corporation

Concurrencyбесконфликтный захват

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

10000

20000

30000

40000

50000

60000

70000

80000

90000

100000

110000

120000

130000

140000

150000

Uncontended Lock Performance

intrinsic jucReentrantL (non-fair) jucReentrantL (fair)

Threads

op

sse

c

41 copy JavaTechDays 2011 Oracle Corporation

Concurrencyконфликтный захват

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

500

1000

1500

2000

2500

3000

3500

4000

4500

Contended Lock Performance

intrinsic jucReentrantL (non-fair) jucReentrantL (fair)

Threads

op

sse

c

43 copy 2011 JavaTechDays Oracle Corporation

bull hellip естьbull hellip работаетbull hellip работает хорошоbull hellip знает о железе всё

ndash Количество и тип CPUndash Поддерживаемые инcтрукции (SSEx AVX VIS)ndash Топологию памяти (в тч размеры кэшей и их характеристики)

bull hellip знает о приложении много всегоndash Иерархию загруженных классовndash Актуальную статистику создания объектовndash Горячий кодndash Какие ветвления исполнялисьndash Какие значения использовалисьndash Многое другое

bull hellip не боится использовать эти знания для компиляции

JITфакты

44 copy 2011 JavaTechDays Oracle Corporation

JITоптимизации

46 copy 2011 JavaTechDays Oracle Corporation

JITкак писать код

bull Используйте стандартные библиотекиndash Зачем писать собственный стандартный контейнер

bull Используйте высокоуровневый API ndash javautilndash javautilconcurrentndash NIO NIO2ndash вообще библиотеки

bull Код должен правильным и понятнымndash Сначала правильноndash Потом алгоритмически ldquoбыстроrdquondash Код не должен быть JIT-oriented

bull Правильно используйте возможности языкаndash EPIC FAIL штатная передача управления exceptionамиndash FAIL Возврат ldquoисключенияrdquo через return ltкод_ошибкиgtndash FAIL int вместо Enum или boolean

47 copy 2011 JavaTechDays Oracle Corporation

Как получить ассемблерный код метода

ndash Обычным дебаггером )

ndash JVMTI

ndash -XX+PrintAssemblybull httpwikissuncomdisplayHotSpotInternalsPrintAssembly

JITдля любопытных

54 copy JavaTechDays 2011 Oracle Corporation

StartupEclipse

bull Типичная конфигурацияndash 2x2 Intel i5 26 Ghz Ubuntu 1010 i686 JDK 6u25ndash Eclipse JDT (Galileo)

bull Типичные метрикиndash 6000 загруженных классовndash 1000 методов скомпилированоndash 512 Mb зарезервированного пространства в кучеndash 25 Mb кучи использовано после стартапа

bull Известные ldquoпроблемыrdquondash Загрузка и верификация классовndash JIT-компиляция

55 copy JavaTechDays 2011 Oracle Corporation

StartupEclipse

bull Метрика секунд на запуск-завершениеndash Файловые кеши прогреты практически нулевой дисковый IO

default CDS CDS + no-verify

абсолютное время

583 [574 592]

481[473 484]

461[456 474]

загрузка классов

501[491 511]

339[312 366]

301[294 308]

компиляция 051[043 059]

051[044 058]

051[042 060]

56 copy JavaTechDays 2011 Oracle Corporation

Startupдлинные приложения

bull Важно только для коротких приложенийndash Чем дольше работает приложение тем меньше удельные затраты на

загрузку классов и компиляцию

bull Пример 8 часа работает IntelliJ IDEA 10xndash 26600 классов загруженоndash 5315 методов скомпилировано

bull Загрузка классовndash Всего потрачено 202 с ~07 общего времениndash 10 мсек на класс

bull Компиляцияndash Всего потрачено 112 с ~003 общего времениndash 20 мсек на метод

57 copy JavaTechDays 2011 Oracle Corporation

Whats Next

bull Послушать ещёndash JavaOne Moscow (апрель 2011)

bull Проблема со слайдамиndash Найдите нас на конференцииndash Напишите нам письмо

bull Проблема с JDKndash httpopenjdkjavanetndash Задайте вопрос в OpenJDKndash а лучше сделайте патч и дайте его в OpenJDK на review

58 copy JavaTechDays 2011 Oracle Corporation

QA

Page 9: Java Platform Performance BoF - Aleksey Shipilëv · – 2x2 Intel i5 2.6 Ghz, Ubuntu 10.10 i686, JDK 6u25 • Три варианта эксперимента: – 1 экземпляр

14 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingнаша стратегия

bull Сделать реальные приложения быстрееndash Но слишком сложно поддерживать и запускатьndash Поэтому

bull Сфокусироваться на синтетических бенчмарках и авто-сценарияхndash SPECjbb SPECjvm SPECjAppServer SPECjEnterprisendash Glassfish Weblogic NetBeans и тпndash Большие in-house нагрузки

bull Пользоваться микробенчмарками с опаскойndash Иногда от них никуда не детьсяndash Очень легко написать очень легко запуститьndash Очень легко ldquoвыстрелить себе в ногуrdquondash что чуть ли не каждую неделю демонстрируется в профильных

блогах

15 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingитак вы решили написать свой бенчмарк

bull Опасайтесь типичных ошибокbull Дизайн эксперимента

ndash Что хотим измеритьndash Каким способом будем измерять

bull Реализация экспериментаndash Отсутствие прогрева ldquoмёртвый кодrdquo etcndash Многопоточность утилизацияndash Контроль переменных результат воспроизводитсяndash Контроль переменных результат вообще зависит от входов

bull Интерпретация результатовndash Что в итоге измерилиndash Значим ли результат

bull 1000 opssec против 1050 opssec ndash прирост или нет

16 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingближе к делу пример

bull Computer Language Benchmark Gamendash httpshootoutaliothdebianorgndash Самый известный полигон для расстрела невинных ног

bull Тест ldquoPiDigitsrdquondash Вычислить первые N цифр в десятичном разложении πndash Вычисляется приближение π специальным рядом

bull Требуется arbitrary precision для представления рациональных членов ряда

ndash Потенциально параллелизуемаndash Две версии Java-теста

bull Текущая использует GNU MP внутренне параллельна 240 строк кода Java + нативные врапперы + GMP

bull Предыдущая использует BigInteger не параллельна 130 строк кода plain Java

17 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingближе к делу пример

bull Computer Language Benchmark Gamendash httpshootoutaliothdebianorgndash Самый известный полигон для расстрела невинных ног

bull Тест ldquoPiDigitsrdquondash Вычислить первые N цифр в десятичном разложении πndash Вычисляется приближение π специальным рядом

bull Требуется arbitrary precision для представления рациональных членов ряда

ndash Потенциально параллелизуемаndash Две версии Java-теста

bull Текущая использует GNU MP внутренне параллельна 240 строк кода Java + нативные врапперы + GMP

bull Предыдущая использует BigInteger не параллельна 130 строк кода plain Java

18 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingближе к делу пример

bull Метрика время исполненияndash time java -server pidigits 1000

bull ldquoПрогреемrdquo

pidigitsjavasteady public static void main(String[] args) pidigits m = new pidigits(IntegerparseInt(args[0])) for (int i=0 ilt65 ++i) mpidigits(false) mpidigits(true)

19 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingближе к делу пример

bull Метрика время исполненияndash time java -server pidigits 1000

bull ldquoПрогреемrdquo

pidigitsjavasteady public static void main(String[] args) pidigits m = new pidigits(IntegerparseInt(args[0])) for (int i=0 ilt65 ++i) mpidigits(false) mpidigits(true)

20 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingближе к делу пример

bull Метрика время исполненияndash time java -server pidigits 1000

bull ldquoПрогреемrdquo

pidigitsjava public static void main(String[] args) pidigits m = new pidigits(IntegerparseInt(args[0])) for (int i=0 ilt19 ++i) mpidigits(false) mpidigits(true)

pidigitsjavasteady public static void main(String[] args) pidigits m = new pidigits(IntegerparseInt(args[0])) for (int i=0 ilt65 ++i) mpidigits(false) mpidigits(true)

21 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingв век многоядерных систем

bull Обычная платформаndash 2x2 Intel i5 26 Ghz Ubuntu 1010 i686 JDK 6u25

bull Три варианта экспериментаndash 1 экземпляр бенчмарка

bull по ldquoметодологии CLBGrdquo (+ корректный прогрев)

bull GMP будет использовать 1x4=4 потока

bull BI будет использовать 1x1=1 поток

ndash 4 экземпляра бенчмарка

bull чтобы утилизировать все ядра = снормировать на систему

bull GMP будет использовать 4х4=16 потоков

bull BI будет использовать 4x1=4 потока

ndash 16 потоков

bull ради одинаковой нагрузки на OS = снормировать на систему+OS

bull GMP будет использовать 4х4=16 потоков

bull BI будет работать в 16x1=16 потоков

bull Какой из них наиболее релевантен

22 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingа вот и данные

1 экземпляр 4 экземпляра 16 потоков

ldquoGMPrdquo

884[869 899]

1328 [1286 1371]

1328 [1286 1371]

ldquoBigIntegerrdquo

621 [619 624]

1346 [1335 1356]

1434 [1421 1446]

bull Метрика операции в секундуndash 20 итерацийndash [a b] ndash доверительный интервал на 95

24 copy JavaTechDays 2011 Oracle Corporation

Java 7 Java 8что ожидать в области производительности

bull Java 7ndash invokedynamicndash NIO2ndash Concurrency and Collection updates (ForkJoin)ndash XRender pipeline for Java2D (client)

bull Java 8 (или позже)ndash Модульностьndash -выражения (замыкания)ndash Collection updates (filter map reduce)

25 copy JavaTechDays 2011 Oracle Corporation

bull Мешает ли улучшать производительность JVMndash Да поэтому иногда расширяемся

bull invokedynamicbull Модульность

bull Стоит ли расширяться по первому требованию ndash Нет развитие JVMJIT реализация новых методов оптимизации

позволяет получить бОльший выигрышbull Вложенные классыbull Reflection

Обратная совместимость

26 copy JavaTechDays 2011 Oracle Corporation

Solaris

Лучшая ОС для Javaугадайте какая

bull Высокопроизводительный TCPIP стекndash low-latencyndash up to 50 faster

bull DTracendash мониторинг

bull NUMAndash MPO Memory Placement Optimization

bull Large Pagesndash Автоматическая аллокацияndash Разные размеры

27 copy JavaTechDays 2011 Oracle Corporation

hellip and beyondнастройка параметров JVM

bull Что настраиватьndash httpblogssuncomwattresourcejvm-options-listhtml

ndash httpwwworaclecomtechnetworkjavajavasetechvmoptions-jsp-140102html

bull JVM сама подбирает оптимальные параметры своей работыndash Server vs Client ndash Large pages (Solaris)ndash CompressedOops (64-bit VM)

bull Так что же настраиватьndash GCHeap tuningndash -XX+UseNUMA (Solaris Linux)ndash -XX+UseLargePages (Linux Windows)

bull httpwwworaclecomtechnetworkjavajavasetechlargememory-jsp-137182html

bull Не забытьndash Использовать последнюю версию JDK

29 copy JavaTechDays 2011 Oracle Corporation

Concurrencyэлементная база

bull OS Threadingndash мьютексы

bull mutex_lock()mutex_unlock()ndash conditional waits

bull cond_wait()cond_signal()bull WaitForSingleObject

bull Compare-and-Swap (CAS)ndash CAS(x1 x2 x3) = if (x1 == x2) x1 = x3 ndash атомарная операция поддерживаемая в ldquoжелезеrdquo из нескольких

одновременных CASов успешно завершается только одинndash Миф локальный CAS блокирует шину и стоит больше на

многопроцессорных системах ndash Факт глобальный CAS требует трафика на шине

httpblogssuncomdaveentrybiased_locking_in_hotspot

30 copy JavaTechDays 2011 Oracle Corporation

Concurrencyatomics

bull javautilconcurrentAtomicndash обеспечивают атомарные операции над примитивами и указателямиndash альтернатива synchronized или Lockи

bull Трюк в использовании CASаndash Изменение состояния атомика делается при помощи одного CASаndash Чтение состояния не требует CASа

public final int incrementAndGet() for () int current = get() int next = current + 1 if (compareAndSet(current next)) return next

mov ecxedxmov 0x8(ecx)eaxlea 0x8(ecx)edimov eaxecxinc ecxlock cmpxchg ecx(edi)mov $0x0ebxjne [ok]mov $0x1ebxtest ebxebxje [ok]

31 copy JavaTechDays 2011 Oracle Corporation

Concurrencyvolatile

bull Volatile определяет порядок чтения-записей в полеndash Точная семантика определена в Java Memory Model

bull НЕ обеспечивает атомарностиndash Реализуется расстановкой барьеров

bull Какие из них вставятся в код зависит от Hardware Memory Modelbull Эффект барьера зависит от HMM

PUSHL EBPSUB ESP8MOV EBX[ECX + 12]MEMBAR-acquireMEMBAR-releaseINC EBXMOV [ECX + 12]EBXMEMBAR-volatileLOCK ADDL [ESP + 0] 0ADD ESP8POPL EBPTEST PollPageEAXRET

push ebpsub $0x8espmov 0xc(ecx)ebxinc ebxmov ebx0xc(ecx)lock addl $0x0(esp)add $0x8esppop ebptest eax0xb779c000ret

httpgoswegoedudljmmcookbookhtml

32 copy JavaTechDays 2011 Oracle Corporation

Concurrencyvolatile-счётчик

public class VolatileTest

private int counter = 0 private volatile int volatileCounter = 0

GenerateMicroBenchmark public void testOrdinary() counter++

GenerateMicroBenchmark public void testVolatile() volatileCounter++

33 copy JavaTechDays 2011 Oracle Corporation

Concurrencyбесконфликтный volatile-счётчик

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

500000

1000000

1500000

2000000

2500000

3000000

3500000

Thread-local counter performance

ordinary volatile

Threads

op

ss

ec

34 copy JavaTechDays 2011 Oracle Corporation

Concurrencyконфликтный volatile-счётчик

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

100000

200000

300000

400000

500000

600000

700000

800000

900000

Global counter performance

ordinary volatile

Threads

op

ss

ec

35 copy JavaTechDays 2011 Oracle Corporation

Concurrencyintrinsic synchronization

bull synchronized(object) bull 4 состояния

ndash Initbull Начальное ldquoнеопределённоеrdquo состояние

ndash Biasedbull Захватывается одним ldquoвладеющимrdquo потоком нет конфликтовbull Захват владельцем проверка на threadIDbull Захват не-владельцем переход либо в Biased либо в Thin

ndash Thinbull Захватывается несколькими потоками но конфликтов нетbull Захват CASbull Конфликтный захват переход в Fat

ndash Fatbull Захватывается несколькими потоками конфликт на блокировкеbull Вызов примитива синхронизации из ОС

36 copy JavaTechDays 2011 Oracle Corporation

ConcurrencyjavautilconcurrentLock

bull Построены на базе jucAbstractQueueSynchronizerndash Использует атомики

bull CAS

ndash Использует Unsafepark()unpark()

bull интринзики для cond_wait()cond_signal()WaitForSingleObject()

bull ReentrantLockndash По семантике эквивалентен synchronized

bull Рекурсивный захват проверка на threadID

bull Ставит потоки во внутреннюю очередь и делает park()

ndash Non-Fair (default)

bull Не гарантирует отсутствие starvation

bull Barging FIFO (CAS)

bull Лучшая производительность

ndash Fair

bull Гарантирует отсутствие starvation

bull FIFO

bull Честность в обмен на производительностьhttpgeecsoswegoedudlpapersaqspdf

37 copy JavaTechDays 2011 Oracle Corporation

Concurrencyатомарный счётчик

private AtomicInteger atomic = new AtomicInteger() private ReentrantLock lock = new ReentrantLock() private final Object intrinsicLock = new Object() private int primCounter = 0

GenerateMicroBenchmark public void testAtomicInteger() atomicincrementAndGet()

GenerateMicroBenchmark public void testReentrantLock() locklock() primCounter++ lockunlock()

GenerateMicroBenchmark public void testIntrinsicLock() synchronized (intrinsicLock) primCounter++

38 copy JavaTechDays 2011 Oracle Corporation

Concurrencyатомарный счётчик

0 16 32 48 64 80 96 112 128

1000

10000

100000

Atomic Counter Performance

Intrinsic AtomicInteger ReentrantLock

Threads

ops

sec

8x8 CPUs Solaris 6u25

39 copy JavaTechDays 2011 Oracle Corporation

ConcurrencyReentrantLock vs synchronized

bull Семантика одинаковаndash Требования к видимости памяти

ndash Рекурсивный

bull Плюсы jucRLndash Очередь потоков держится на стороне JVM

bull опционально FIFO-политика при захвате-освобождении

bull позволяет быть ldquoчестнымrdquo на любой платформе

ndash Barging FIFO policy

bull lock() может быть сразу удовлетворён даже если в очереди есть потоки

bull сильно улучшает производительность при конфликте блокировок

ndash Допускается несколько Condition

bull Минусы jucRLndash Нет scopeов требуется ручной unlock() через finally

bull Должно быть проще с ARM в JDK7

40 copy JavaTechDays 2011 Oracle Corporation

Concurrencyбесконфликтный захват

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

10000

20000

30000

40000

50000

60000

70000

80000

90000

100000

110000

120000

130000

140000

150000

Uncontended Lock Performance

intrinsic jucReentrantL (non-fair) jucReentrantL (fair)

Threads

op

sse

c

41 copy JavaTechDays 2011 Oracle Corporation

Concurrencyконфликтный захват

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

500

1000

1500

2000

2500

3000

3500

4000

4500

Contended Lock Performance

intrinsic jucReentrantL (non-fair) jucReentrantL (fair)

Threads

op

sse

c

43 copy 2011 JavaTechDays Oracle Corporation

bull hellip естьbull hellip работаетbull hellip работает хорошоbull hellip знает о железе всё

ndash Количество и тип CPUndash Поддерживаемые инcтрукции (SSEx AVX VIS)ndash Топологию памяти (в тч размеры кэшей и их характеристики)

bull hellip знает о приложении много всегоndash Иерархию загруженных классовndash Актуальную статистику создания объектовndash Горячий кодndash Какие ветвления исполнялисьndash Какие значения использовалисьndash Многое другое

bull hellip не боится использовать эти знания для компиляции

JITфакты

44 copy 2011 JavaTechDays Oracle Corporation

JITоптимизации

46 copy 2011 JavaTechDays Oracle Corporation

JITкак писать код

bull Используйте стандартные библиотекиndash Зачем писать собственный стандартный контейнер

bull Используйте высокоуровневый API ndash javautilndash javautilconcurrentndash NIO NIO2ndash вообще библиотеки

bull Код должен правильным и понятнымndash Сначала правильноndash Потом алгоритмически ldquoбыстроrdquondash Код не должен быть JIT-oriented

bull Правильно используйте возможности языкаndash EPIC FAIL штатная передача управления exceptionамиndash FAIL Возврат ldquoисключенияrdquo через return ltкод_ошибкиgtndash FAIL int вместо Enum или boolean

47 copy 2011 JavaTechDays Oracle Corporation

Как получить ассемблерный код метода

ndash Обычным дебаггером )

ndash JVMTI

ndash -XX+PrintAssemblybull httpwikissuncomdisplayHotSpotInternalsPrintAssembly

JITдля любопытных

54 copy JavaTechDays 2011 Oracle Corporation

StartupEclipse

bull Типичная конфигурацияndash 2x2 Intel i5 26 Ghz Ubuntu 1010 i686 JDK 6u25ndash Eclipse JDT (Galileo)

bull Типичные метрикиndash 6000 загруженных классовndash 1000 методов скомпилированоndash 512 Mb зарезервированного пространства в кучеndash 25 Mb кучи использовано после стартапа

bull Известные ldquoпроблемыrdquondash Загрузка и верификация классовndash JIT-компиляция

55 copy JavaTechDays 2011 Oracle Corporation

StartupEclipse

bull Метрика секунд на запуск-завершениеndash Файловые кеши прогреты практически нулевой дисковый IO

default CDS CDS + no-verify

абсолютное время

583 [574 592]

481[473 484]

461[456 474]

загрузка классов

501[491 511]

339[312 366]

301[294 308]

компиляция 051[043 059]

051[044 058]

051[042 060]

56 copy JavaTechDays 2011 Oracle Corporation

Startupдлинные приложения

bull Важно только для коротких приложенийndash Чем дольше работает приложение тем меньше удельные затраты на

загрузку классов и компиляцию

bull Пример 8 часа работает IntelliJ IDEA 10xndash 26600 классов загруженоndash 5315 методов скомпилировано

bull Загрузка классовndash Всего потрачено 202 с ~07 общего времениndash 10 мсек на класс

bull Компиляцияndash Всего потрачено 112 с ~003 общего времениndash 20 мсек на метод

57 copy JavaTechDays 2011 Oracle Corporation

Whats Next

bull Послушать ещёndash JavaOne Moscow (апрель 2011)

bull Проблема со слайдамиndash Найдите нас на конференцииndash Напишите нам письмо

bull Проблема с JDKndash httpopenjdkjavanetndash Задайте вопрос в OpenJDKndash а лучше сделайте патч и дайте его в OpenJDK на review

58 copy JavaTechDays 2011 Oracle Corporation

QA

Page 10: Java Platform Performance BoF - Aleksey Shipilëv · – 2x2 Intel i5 2.6 Ghz, Ubuntu 10.10 i686, JDK 6u25 • Три варианта эксперимента: – 1 экземпляр

15 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingитак вы решили написать свой бенчмарк

bull Опасайтесь типичных ошибокbull Дизайн эксперимента

ndash Что хотим измеритьndash Каким способом будем измерять

bull Реализация экспериментаndash Отсутствие прогрева ldquoмёртвый кодrdquo etcndash Многопоточность утилизацияndash Контроль переменных результат воспроизводитсяndash Контроль переменных результат вообще зависит от входов

bull Интерпретация результатовndash Что в итоге измерилиndash Значим ли результат

bull 1000 opssec против 1050 opssec ndash прирост или нет

16 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingближе к делу пример

bull Computer Language Benchmark Gamendash httpshootoutaliothdebianorgndash Самый известный полигон для расстрела невинных ног

bull Тест ldquoPiDigitsrdquondash Вычислить первые N цифр в десятичном разложении πndash Вычисляется приближение π специальным рядом

bull Требуется arbitrary precision для представления рациональных членов ряда

ndash Потенциально параллелизуемаndash Две версии Java-теста

bull Текущая использует GNU MP внутренне параллельна 240 строк кода Java + нативные врапперы + GMP

bull Предыдущая использует BigInteger не параллельна 130 строк кода plain Java

17 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingближе к делу пример

bull Computer Language Benchmark Gamendash httpshootoutaliothdebianorgndash Самый известный полигон для расстрела невинных ног

bull Тест ldquoPiDigitsrdquondash Вычислить первые N цифр в десятичном разложении πndash Вычисляется приближение π специальным рядом

bull Требуется arbitrary precision для представления рациональных членов ряда

ndash Потенциально параллелизуемаndash Две версии Java-теста

bull Текущая использует GNU MP внутренне параллельна 240 строк кода Java + нативные врапперы + GMP

bull Предыдущая использует BigInteger не параллельна 130 строк кода plain Java

18 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingближе к делу пример

bull Метрика время исполненияndash time java -server pidigits 1000

bull ldquoПрогреемrdquo

pidigitsjavasteady public static void main(String[] args) pidigits m = new pidigits(IntegerparseInt(args[0])) for (int i=0 ilt65 ++i) mpidigits(false) mpidigits(true)

19 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingближе к делу пример

bull Метрика время исполненияndash time java -server pidigits 1000

bull ldquoПрогреемrdquo

pidigitsjavasteady public static void main(String[] args) pidigits m = new pidigits(IntegerparseInt(args[0])) for (int i=0 ilt65 ++i) mpidigits(false) mpidigits(true)

20 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingближе к делу пример

bull Метрика время исполненияndash time java -server pidigits 1000

bull ldquoПрогреемrdquo

pidigitsjava public static void main(String[] args) pidigits m = new pidigits(IntegerparseInt(args[0])) for (int i=0 ilt19 ++i) mpidigits(false) mpidigits(true)

pidigitsjavasteady public static void main(String[] args) pidigits m = new pidigits(IntegerparseInt(args[0])) for (int i=0 ilt65 ++i) mpidigits(false) mpidigits(true)

21 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingв век многоядерных систем

bull Обычная платформаndash 2x2 Intel i5 26 Ghz Ubuntu 1010 i686 JDK 6u25

bull Три варианта экспериментаndash 1 экземпляр бенчмарка

bull по ldquoметодологии CLBGrdquo (+ корректный прогрев)

bull GMP будет использовать 1x4=4 потока

bull BI будет использовать 1x1=1 поток

ndash 4 экземпляра бенчмарка

bull чтобы утилизировать все ядра = снормировать на систему

bull GMP будет использовать 4х4=16 потоков

bull BI будет использовать 4x1=4 потока

ndash 16 потоков

bull ради одинаковой нагрузки на OS = снормировать на систему+OS

bull GMP будет использовать 4х4=16 потоков

bull BI будет работать в 16x1=16 потоков

bull Какой из них наиболее релевантен

22 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingа вот и данные

1 экземпляр 4 экземпляра 16 потоков

ldquoGMPrdquo

884[869 899]

1328 [1286 1371]

1328 [1286 1371]

ldquoBigIntegerrdquo

621 [619 624]

1346 [1335 1356]

1434 [1421 1446]

bull Метрика операции в секундуndash 20 итерацийndash [a b] ndash доверительный интервал на 95

24 copy JavaTechDays 2011 Oracle Corporation

Java 7 Java 8что ожидать в области производительности

bull Java 7ndash invokedynamicndash NIO2ndash Concurrency and Collection updates (ForkJoin)ndash XRender pipeline for Java2D (client)

bull Java 8 (или позже)ndash Модульностьndash -выражения (замыкания)ndash Collection updates (filter map reduce)

25 copy JavaTechDays 2011 Oracle Corporation

bull Мешает ли улучшать производительность JVMndash Да поэтому иногда расширяемся

bull invokedynamicbull Модульность

bull Стоит ли расширяться по первому требованию ndash Нет развитие JVMJIT реализация новых методов оптимизации

позволяет получить бОльший выигрышbull Вложенные классыbull Reflection

Обратная совместимость

26 copy JavaTechDays 2011 Oracle Corporation

Solaris

Лучшая ОС для Javaугадайте какая

bull Высокопроизводительный TCPIP стекndash low-latencyndash up to 50 faster

bull DTracendash мониторинг

bull NUMAndash MPO Memory Placement Optimization

bull Large Pagesndash Автоматическая аллокацияndash Разные размеры

27 copy JavaTechDays 2011 Oracle Corporation

hellip and beyondнастройка параметров JVM

bull Что настраиватьndash httpblogssuncomwattresourcejvm-options-listhtml

ndash httpwwworaclecomtechnetworkjavajavasetechvmoptions-jsp-140102html

bull JVM сама подбирает оптимальные параметры своей работыndash Server vs Client ndash Large pages (Solaris)ndash CompressedOops (64-bit VM)

bull Так что же настраиватьndash GCHeap tuningndash -XX+UseNUMA (Solaris Linux)ndash -XX+UseLargePages (Linux Windows)

bull httpwwworaclecomtechnetworkjavajavasetechlargememory-jsp-137182html

bull Не забытьndash Использовать последнюю версию JDK

29 copy JavaTechDays 2011 Oracle Corporation

Concurrencyэлементная база

bull OS Threadingndash мьютексы

bull mutex_lock()mutex_unlock()ndash conditional waits

bull cond_wait()cond_signal()bull WaitForSingleObject

bull Compare-and-Swap (CAS)ndash CAS(x1 x2 x3) = if (x1 == x2) x1 = x3 ndash атомарная операция поддерживаемая в ldquoжелезеrdquo из нескольких

одновременных CASов успешно завершается только одинndash Миф локальный CAS блокирует шину и стоит больше на

многопроцессорных системах ndash Факт глобальный CAS требует трафика на шине

httpblogssuncomdaveentrybiased_locking_in_hotspot

30 copy JavaTechDays 2011 Oracle Corporation

Concurrencyatomics

bull javautilconcurrentAtomicndash обеспечивают атомарные операции над примитивами и указателямиndash альтернатива synchronized или Lockи

bull Трюк в использовании CASаndash Изменение состояния атомика делается при помощи одного CASаndash Чтение состояния не требует CASа

public final int incrementAndGet() for () int current = get() int next = current + 1 if (compareAndSet(current next)) return next

mov ecxedxmov 0x8(ecx)eaxlea 0x8(ecx)edimov eaxecxinc ecxlock cmpxchg ecx(edi)mov $0x0ebxjne [ok]mov $0x1ebxtest ebxebxje [ok]

31 copy JavaTechDays 2011 Oracle Corporation

Concurrencyvolatile

bull Volatile определяет порядок чтения-записей в полеndash Точная семантика определена в Java Memory Model

bull НЕ обеспечивает атомарностиndash Реализуется расстановкой барьеров

bull Какие из них вставятся в код зависит от Hardware Memory Modelbull Эффект барьера зависит от HMM

PUSHL EBPSUB ESP8MOV EBX[ECX + 12]MEMBAR-acquireMEMBAR-releaseINC EBXMOV [ECX + 12]EBXMEMBAR-volatileLOCK ADDL [ESP + 0] 0ADD ESP8POPL EBPTEST PollPageEAXRET

push ebpsub $0x8espmov 0xc(ecx)ebxinc ebxmov ebx0xc(ecx)lock addl $0x0(esp)add $0x8esppop ebptest eax0xb779c000ret

httpgoswegoedudljmmcookbookhtml

32 copy JavaTechDays 2011 Oracle Corporation

Concurrencyvolatile-счётчик

public class VolatileTest

private int counter = 0 private volatile int volatileCounter = 0

GenerateMicroBenchmark public void testOrdinary() counter++

GenerateMicroBenchmark public void testVolatile() volatileCounter++

33 copy JavaTechDays 2011 Oracle Corporation

Concurrencyбесконфликтный volatile-счётчик

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

500000

1000000

1500000

2000000

2500000

3000000

3500000

Thread-local counter performance

ordinary volatile

Threads

op

ss

ec

34 copy JavaTechDays 2011 Oracle Corporation

Concurrencyконфликтный volatile-счётчик

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

100000

200000

300000

400000

500000

600000

700000

800000

900000

Global counter performance

ordinary volatile

Threads

op

ss

ec

35 copy JavaTechDays 2011 Oracle Corporation

Concurrencyintrinsic synchronization

bull synchronized(object) bull 4 состояния

ndash Initbull Начальное ldquoнеопределённоеrdquo состояние

ndash Biasedbull Захватывается одним ldquoвладеющимrdquo потоком нет конфликтовbull Захват владельцем проверка на threadIDbull Захват не-владельцем переход либо в Biased либо в Thin

ndash Thinbull Захватывается несколькими потоками но конфликтов нетbull Захват CASbull Конфликтный захват переход в Fat

ndash Fatbull Захватывается несколькими потоками конфликт на блокировкеbull Вызов примитива синхронизации из ОС

36 copy JavaTechDays 2011 Oracle Corporation

ConcurrencyjavautilconcurrentLock

bull Построены на базе jucAbstractQueueSynchronizerndash Использует атомики

bull CAS

ndash Использует Unsafepark()unpark()

bull интринзики для cond_wait()cond_signal()WaitForSingleObject()

bull ReentrantLockndash По семантике эквивалентен synchronized

bull Рекурсивный захват проверка на threadID

bull Ставит потоки во внутреннюю очередь и делает park()

ndash Non-Fair (default)

bull Не гарантирует отсутствие starvation

bull Barging FIFO (CAS)

bull Лучшая производительность

ndash Fair

bull Гарантирует отсутствие starvation

bull FIFO

bull Честность в обмен на производительностьhttpgeecsoswegoedudlpapersaqspdf

37 copy JavaTechDays 2011 Oracle Corporation

Concurrencyатомарный счётчик

private AtomicInteger atomic = new AtomicInteger() private ReentrantLock lock = new ReentrantLock() private final Object intrinsicLock = new Object() private int primCounter = 0

GenerateMicroBenchmark public void testAtomicInteger() atomicincrementAndGet()

GenerateMicroBenchmark public void testReentrantLock() locklock() primCounter++ lockunlock()

GenerateMicroBenchmark public void testIntrinsicLock() synchronized (intrinsicLock) primCounter++

38 copy JavaTechDays 2011 Oracle Corporation

Concurrencyатомарный счётчик

0 16 32 48 64 80 96 112 128

1000

10000

100000

Atomic Counter Performance

Intrinsic AtomicInteger ReentrantLock

Threads

ops

sec

8x8 CPUs Solaris 6u25

39 copy JavaTechDays 2011 Oracle Corporation

ConcurrencyReentrantLock vs synchronized

bull Семантика одинаковаndash Требования к видимости памяти

ndash Рекурсивный

bull Плюсы jucRLndash Очередь потоков держится на стороне JVM

bull опционально FIFO-политика при захвате-освобождении

bull позволяет быть ldquoчестнымrdquo на любой платформе

ndash Barging FIFO policy

bull lock() может быть сразу удовлетворён даже если в очереди есть потоки

bull сильно улучшает производительность при конфликте блокировок

ndash Допускается несколько Condition

bull Минусы jucRLndash Нет scopeов требуется ручной unlock() через finally

bull Должно быть проще с ARM в JDK7

40 copy JavaTechDays 2011 Oracle Corporation

Concurrencyбесконфликтный захват

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

10000

20000

30000

40000

50000

60000

70000

80000

90000

100000

110000

120000

130000

140000

150000

Uncontended Lock Performance

intrinsic jucReentrantL (non-fair) jucReentrantL (fair)

Threads

op

sse

c

41 copy JavaTechDays 2011 Oracle Corporation

Concurrencyконфликтный захват

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

500

1000

1500

2000

2500

3000

3500

4000

4500

Contended Lock Performance

intrinsic jucReentrantL (non-fair) jucReentrantL (fair)

Threads

op

sse

c

43 copy 2011 JavaTechDays Oracle Corporation

bull hellip естьbull hellip работаетbull hellip работает хорошоbull hellip знает о железе всё

ndash Количество и тип CPUndash Поддерживаемые инcтрукции (SSEx AVX VIS)ndash Топологию памяти (в тч размеры кэшей и их характеристики)

bull hellip знает о приложении много всегоndash Иерархию загруженных классовndash Актуальную статистику создания объектовndash Горячий кодndash Какие ветвления исполнялисьndash Какие значения использовалисьndash Многое другое

bull hellip не боится использовать эти знания для компиляции

JITфакты

44 copy 2011 JavaTechDays Oracle Corporation

JITоптимизации

46 copy 2011 JavaTechDays Oracle Corporation

JITкак писать код

bull Используйте стандартные библиотекиndash Зачем писать собственный стандартный контейнер

bull Используйте высокоуровневый API ndash javautilndash javautilconcurrentndash NIO NIO2ndash вообще библиотеки

bull Код должен правильным и понятнымndash Сначала правильноndash Потом алгоритмически ldquoбыстроrdquondash Код не должен быть JIT-oriented

bull Правильно используйте возможности языкаndash EPIC FAIL штатная передача управления exceptionамиndash FAIL Возврат ldquoисключенияrdquo через return ltкод_ошибкиgtndash FAIL int вместо Enum или boolean

47 copy 2011 JavaTechDays Oracle Corporation

Как получить ассемблерный код метода

ndash Обычным дебаггером )

ndash JVMTI

ndash -XX+PrintAssemblybull httpwikissuncomdisplayHotSpotInternalsPrintAssembly

JITдля любопытных

54 copy JavaTechDays 2011 Oracle Corporation

StartupEclipse

bull Типичная конфигурацияndash 2x2 Intel i5 26 Ghz Ubuntu 1010 i686 JDK 6u25ndash Eclipse JDT (Galileo)

bull Типичные метрикиndash 6000 загруженных классовndash 1000 методов скомпилированоndash 512 Mb зарезервированного пространства в кучеndash 25 Mb кучи использовано после стартапа

bull Известные ldquoпроблемыrdquondash Загрузка и верификация классовndash JIT-компиляция

55 copy JavaTechDays 2011 Oracle Corporation

StartupEclipse

bull Метрика секунд на запуск-завершениеndash Файловые кеши прогреты практически нулевой дисковый IO

default CDS CDS + no-verify

абсолютное время

583 [574 592]

481[473 484]

461[456 474]

загрузка классов

501[491 511]

339[312 366]

301[294 308]

компиляция 051[043 059]

051[044 058]

051[042 060]

56 copy JavaTechDays 2011 Oracle Corporation

Startupдлинные приложения

bull Важно только для коротких приложенийndash Чем дольше работает приложение тем меньше удельные затраты на

загрузку классов и компиляцию

bull Пример 8 часа работает IntelliJ IDEA 10xndash 26600 классов загруженоndash 5315 методов скомпилировано

bull Загрузка классовndash Всего потрачено 202 с ~07 общего времениndash 10 мсек на класс

bull Компиляцияndash Всего потрачено 112 с ~003 общего времениndash 20 мсек на метод

57 copy JavaTechDays 2011 Oracle Corporation

Whats Next

bull Послушать ещёndash JavaOne Moscow (апрель 2011)

bull Проблема со слайдамиndash Найдите нас на конференцииndash Напишите нам письмо

bull Проблема с JDKndash httpopenjdkjavanetndash Задайте вопрос в OpenJDKndash а лучше сделайте патч и дайте его в OpenJDK на review

58 copy JavaTechDays 2011 Oracle Corporation

QA

Page 11: Java Platform Performance BoF - Aleksey Shipilëv · – 2x2 Intel i5 2.6 Ghz, Ubuntu 10.10 i686, JDK 6u25 • Три варианта эксперимента: – 1 экземпляр

16 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingближе к делу пример

bull Computer Language Benchmark Gamendash httpshootoutaliothdebianorgndash Самый известный полигон для расстрела невинных ног

bull Тест ldquoPiDigitsrdquondash Вычислить первые N цифр в десятичном разложении πndash Вычисляется приближение π специальным рядом

bull Требуется arbitrary precision для представления рациональных членов ряда

ndash Потенциально параллелизуемаndash Две версии Java-теста

bull Текущая использует GNU MP внутренне параллельна 240 строк кода Java + нативные врапперы + GMP

bull Предыдущая использует BigInteger не параллельна 130 строк кода plain Java

17 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingближе к делу пример

bull Computer Language Benchmark Gamendash httpshootoutaliothdebianorgndash Самый известный полигон для расстрела невинных ног

bull Тест ldquoPiDigitsrdquondash Вычислить первые N цифр в десятичном разложении πndash Вычисляется приближение π специальным рядом

bull Требуется arbitrary precision для представления рациональных членов ряда

ndash Потенциально параллелизуемаndash Две версии Java-теста

bull Текущая использует GNU MP внутренне параллельна 240 строк кода Java + нативные врапперы + GMP

bull Предыдущая использует BigInteger не параллельна 130 строк кода plain Java

18 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingближе к делу пример

bull Метрика время исполненияndash time java -server pidigits 1000

bull ldquoПрогреемrdquo

pidigitsjavasteady public static void main(String[] args) pidigits m = new pidigits(IntegerparseInt(args[0])) for (int i=0 ilt65 ++i) mpidigits(false) mpidigits(true)

19 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingближе к делу пример

bull Метрика время исполненияndash time java -server pidigits 1000

bull ldquoПрогреемrdquo

pidigitsjavasteady public static void main(String[] args) pidigits m = new pidigits(IntegerparseInt(args[0])) for (int i=0 ilt65 ++i) mpidigits(false) mpidigits(true)

20 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingближе к делу пример

bull Метрика время исполненияndash time java -server pidigits 1000

bull ldquoПрогреемrdquo

pidigitsjava public static void main(String[] args) pidigits m = new pidigits(IntegerparseInt(args[0])) for (int i=0 ilt19 ++i) mpidigits(false) mpidigits(true)

pidigitsjavasteady public static void main(String[] args) pidigits m = new pidigits(IntegerparseInt(args[0])) for (int i=0 ilt65 ++i) mpidigits(false) mpidigits(true)

21 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingв век многоядерных систем

bull Обычная платформаndash 2x2 Intel i5 26 Ghz Ubuntu 1010 i686 JDK 6u25

bull Три варианта экспериментаndash 1 экземпляр бенчмарка

bull по ldquoметодологии CLBGrdquo (+ корректный прогрев)

bull GMP будет использовать 1x4=4 потока

bull BI будет использовать 1x1=1 поток

ndash 4 экземпляра бенчмарка

bull чтобы утилизировать все ядра = снормировать на систему

bull GMP будет использовать 4х4=16 потоков

bull BI будет использовать 4x1=4 потока

ndash 16 потоков

bull ради одинаковой нагрузки на OS = снормировать на систему+OS

bull GMP будет использовать 4х4=16 потоков

bull BI будет работать в 16x1=16 потоков

bull Какой из них наиболее релевантен

22 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingа вот и данные

1 экземпляр 4 экземпляра 16 потоков

ldquoGMPrdquo

884[869 899]

1328 [1286 1371]

1328 [1286 1371]

ldquoBigIntegerrdquo

621 [619 624]

1346 [1335 1356]

1434 [1421 1446]

bull Метрика операции в секундуndash 20 итерацийndash [a b] ndash доверительный интервал на 95

24 copy JavaTechDays 2011 Oracle Corporation

Java 7 Java 8что ожидать в области производительности

bull Java 7ndash invokedynamicndash NIO2ndash Concurrency and Collection updates (ForkJoin)ndash XRender pipeline for Java2D (client)

bull Java 8 (или позже)ndash Модульностьndash -выражения (замыкания)ndash Collection updates (filter map reduce)

25 copy JavaTechDays 2011 Oracle Corporation

bull Мешает ли улучшать производительность JVMndash Да поэтому иногда расширяемся

bull invokedynamicbull Модульность

bull Стоит ли расширяться по первому требованию ndash Нет развитие JVMJIT реализация новых методов оптимизации

позволяет получить бОльший выигрышbull Вложенные классыbull Reflection

Обратная совместимость

26 copy JavaTechDays 2011 Oracle Corporation

Solaris

Лучшая ОС для Javaугадайте какая

bull Высокопроизводительный TCPIP стекndash low-latencyndash up to 50 faster

bull DTracendash мониторинг

bull NUMAndash MPO Memory Placement Optimization

bull Large Pagesndash Автоматическая аллокацияndash Разные размеры

27 copy JavaTechDays 2011 Oracle Corporation

hellip and beyondнастройка параметров JVM

bull Что настраиватьndash httpblogssuncomwattresourcejvm-options-listhtml

ndash httpwwworaclecomtechnetworkjavajavasetechvmoptions-jsp-140102html

bull JVM сама подбирает оптимальные параметры своей работыndash Server vs Client ndash Large pages (Solaris)ndash CompressedOops (64-bit VM)

bull Так что же настраиватьndash GCHeap tuningndash -XX+UseNUMA (Solaris Linux)ndash -XX+UseLargePages (Linux Windows)

bull httpwwworaclecomtechnetworkjavajavasetechlargememory-jsp-137182html

bull Не забытьndash Использовать последнюю версию JDK

29 copy JavaTechDays 2011 Oracle Corporation

Concurrencyэлементная база

bull OS Threadingndash мьютексы

bull mutex_lock()mutex_unlock()ndash conditional waits

bull cond_wait()cond_signal()bull WaitForSingleObject

bull Compare-and-Swap (CAS)ndash CAS(x1 x2 x3) = if (x1 == x2) x1 = x3 ndash атомарная операция поддерживаемая в ldquoжелезеrdquo из нескольких

одновременных CASов успешно завершается только одинndash Миф локальный CAS блокирует шину и стоит больше на

многопроцессорных системах ndash Факт глобальный CAS требует трафика на шине

httpblogssuncomdaveentrybiased_locking_in_hotspot

30 copy JavaTechDays 2011 Oracle Corporation

Concurrencyatomics

bull javautilconcurrentAtomicndash обеспечивают атомарные операции над примитивами и указателямиndash альтернатива synchronized или Lockи

bull Трюк в использовании CASаndash Изменение состояния атомика делается при помощи одного CASаndash Чтение состояния не требует CASа

public final int incrementAndGet() for () int current = get() int next = current + 1 if (compareAndSet(current next)) return next

mov ecxedxmov 0x8(ecx)eaxlea 0x8(ecx)edimov eaxecxinc ecxlock cmpxchg ecx(edi)mov $0x0ebxjne [ok]mov $0x1ebxtest ebxebxje [ok]

31 copy JavaTechDays 2011 Oracle Corporation

Concurrencyvolatile

bull Volatile определяет порядок чтения-записей в полеndash Точная семантика определена в Java Memory Model

bull НЕ обеспечивает атомарностиndash Реализуется расстановкой барьеров

bull Какие из них вставятся в код зависит от Hardware Memory Modelbull Эффект барьера зависит от HMM

PUSHL EBPSUB ESP8MOV EBX[ECX + 12]MEMBAR-acquireMEMBAR-releaseINC EBXMOV [ECX + 12]EBXMEMBAR-volatileLOCK ADDL [ESP + 0] 0ADD ESP8POPL EBPTEST PollPageEAXRET

push ebpsub $0x8espmov 0xc(ecx)ebxinc ebxmov ebx0xc(ecx)lock addl $0x0(esp)add $0x8esppop ebptest eax0xb779c000ret

httpgoswegoedudljmmcookbookhtml

32 copy JavaTechDays 2011 Oracle Corporation

Concurrencyvolatile-счётчик

public class VolatileTest

private int counter = 0 private volatile int volatileCounter = 0

GenerateMicroBenchmark public void testOrdinary() counter++

GenerateMicroBenchmark public void testVolatile() volatileCounter++

33 copy JavaTechDays 2011 Oracle Corporation

Concurrencyбесконфликтный volatile-счётчик

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

500000

1000000

1500000

2000000

2500000

3000000

3500000

Thread-local counter performance

ordinary volatile

Threads

op

ss

ec

34 copy JavaTechDays 2011 Oracle Corporation

Concurrencyконфликтный volatile-счётчик

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

100000

200000

300000

400000

500000

600000

700000

800000

900000

Global counter performance

ordinary volatile

Threads

op

ss

ec

35 copy JavaTechDays 2011 Oracle Corporation

Concurrencyintrinsic synchronization

bull synchronized(object) bull 4 состояния

ndash Initbull Начальное ldquoнеопределённоеrdquo состояние

ndash Biasedbull Захватывается одним ldquoвладеющимrdquo потоком нет конфликтовbull Захват владельцем проверка на threadIDbull Захват не-владельцем переход либо в Biased либо в Thin

ndash Thinbull Захватывается несколькими потоками но конфликтов нетbull Захват CASbull Конфликтный захват переход в Fat

ndash Fatbull Захватывается несколькими потоками конфликт на блокировкеbull Вызов примитива синхронизации из ОС

36 copy JavaTechDays 2011 Oracle Corporation

ConcurrencyjavautilconcurrentLock

bull Построены на базе jucAbstractQueueSynchronizerndash Использует атомики

bull CAS

ndash Использует Unsafepark()unpark()

bull интринзики для cond_wait()cond_signal()WaitForSingleObject()

bull ReentrantLockndash По семантике эквивалентен synchronized

bull Рекурсивный захват проверка на threadID

bull Ставит потоки во внутреннюю очередь и делает park()

ndash Non-Fair (default)

bull Не гарантирует отсутствие starvation

bull Barging FIFO (CAS)

bull Лучшая производительность

ndash Fair

bull Гарантирует отсутствие starvation

bull FIFO

bull Честность в обмен на производительностьhttpgeecsoswegoedudlpapersaqspdf

37 copy JavaTechDays 2011 Oracle Corporation

Concurrencyатомарный счётчик

private AtomicInteger atomic = new AtomicInteger() private ReentrantLock lock = new ReentrantLock() private final Object intrinsicLock = new Object() private int primCounter = 0

GenerateMicroBenchmark public void testAtomicInteger() atomicincrementAndGet()

GenerateMicroBenchmark public void testReentrantLock() locklock() primCounter++ lockunlock()

GenerateMicroBenchmark public void testIntrinsicLock() synchronized (intrinsicLock) primCounter++

38 copy JavaTechDays 2011 Oracle Corporation

Concurrencyатомарный счётчик

0 16 32 48 64 80 96 112 128

1000

10000

100000

Atomic Counter Performance

Intrinsic AtomicInteger ReentrantLock

Threads

ops

sec

8x8 CPUs Solaris 6u25

39 copy JavaTechDays 2011 Oracle Corporation

ConcurrencyReentrantLock vs synchronized

bull Семантика одинаковаndash Требования к видимости памяти

ndash Рекурсивный

bull Плюсы jucRLndash Очередь потоков держится на стороне JVM

bull опционально FIFO-политика при захвате-освобождении

bull позволяет быть ldquoчестнымrdquo на любой платформе

ndash Barging FIFO policy

bull lock() может быть сразу удовлетворён даже если в очереди есть потоки

bull сильно улучшает производительность при конфликте блокировок

ndash Допускается несколько Condition

bull Минусы jucRLndash Нет scopeов требуется ручной unlock() через finally

bull Должно быть проще с ARM в JDK7

40 copy JavaTechDays 2011 Oracle Corporation

Concurrencyбесконфликтный захват

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

10000

20000

30000

40000

50000

60000

70000

80000

90000

100000

110000

120000

130000

140000

150000

Uncontended Lock Performance

intrinsic jucReentrantL (non-fair) jucReentrantL (fair)

Threads

op

sse

c

41 copy JavaTechDays 2011 Oracle Corporation

Concurrencyконфликтный захват

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

500

1000

1500

2000

2500

3000

3500

4000

4500

Contended Lock Performance

intrinsic jucReentrantL (non-fair) jucReentrantL (fair)

Threads

op

sse

c

43 copy 2011 JavaTechDays Oracle Corporation

bull hellip естьbull hellip работаетbull hellip работает хорошоbull hellip знает о железе всё

ndash Количество и тип CPUndash Поддерживаемые инcтрукции (SSEx AVX VIS)ndash Топологию памяти (в тч размеры кэшей и их характеристики)

bull hellip знает о приложении много всегоndash Иерархию загруженных классовndash Актуальную статистику создания объектовndash Горячий кодndash Какие ветвления исполнялисьndash Какие значения использовалисьndash Многое другое

bull hellip не боится использовать эти знания для компиляции

JITфакты

44 copy 2011 JavaTechDays Oracle Corporation

JITоптимизации

46 copy 2011 JavaTechDays Oracle Corporation

JITкак писать код

bull Используйте стандартные библиотекиndash Зачем писать собственный стандартный контейнер

bull Используйте высокоуровневый API ndash javautilndash javautilconcurrentndash NIO NIO2ndash вообще библиотеки

bull Код должен правильным и понятнымndash Сначала правильноndash Потом алгоритмически ldquoбыстроrdquondash Код не должен быть JIT-oriented

bull Правильно используйте возможности языкаndash EPIC FAIL штатная передача управления exceptionамиndash FAIL Возврат ldquoисключенияrdquo через return ltкод_ошибкиgtndash FAIL int вместо Enum или boolean

47 copy 2011 JavaTechDays Oracle Corporation

Как получить ассемблерный код метода

ndash Обычным дебаггером )

ndash JVMTI

ndash -XX+PrintAssemblybull httpwikissuncomdisplayHotSpotInternalsPrintAssembly

JITдля любопытных

54 copy JavaTechDays 2011 Oracle Corporation

StartupEclipse

bull Типичная конфигурацияndash 2x2 Intel i5 26 Ghz Ubuntu 1010 i686 JDK 6u25ndash Eclipse JDT (Galileo)

bull Типичные метрикиndash 6000 загруженных классовndash 1000 методов скомпилированоndash 512 Mb зарезервированного пространства в кучеndash 25 Mb кучи использовано после стартапа

bull Известные ldquoпроблемыrdquondash Загрузка и верификация классовndash JIT-компиляция

55 copy JavaTechDays 2011 Oracle Corporation

StartupEclipse

bull Метрика секунд на запуск-завершениеndash Файловые кеши прогреты практически нулевой дисковый IO

default CDS CDS + no-verify

абсолютное время

583 [574 592]

481[473 484]

461[456 474]

загрузка классов

501[491 511]

339[312 366]

301[294 308]

компиляция 051[043 059]

051[044 058]

051[042 060]

56 copy JavaTechDays 2011 Oracle Corporation

Startupдлинные приложения

bull Важно только для коротких приложенийndash Чем дольше работает приложение тем меньше удельные затраты на

загрузку классов и компиляцию

bull Пример 8 часа работает IntelliJ IDEA 10xndash 26600 классов загруженоndash 5315 методов скомпилировано

bull Загрузка классовndash Всего потрачено 202 с ~07 общего времениndash 10 мсек на класс

bull Компиляцияndash Всего потрачено 112 с ~003 общего времениndash 20 мсек на метод

57 copy JavaTechDays 2011 Oracle Corporation

Whats Next

bull Послушать ещёndash JavaOne Moscow (апрель 2011)

bull Проблема со слайдамиndash Найдите нас на конференцииndash Напишите нам письмо

bull Проблема с JDKndash httpopenjdkjavanetndash Задайте вопрос в OpenJDKndash а лучше сделайте патч и дайте его в OpenJDK на review

58 copy JavaTechDays 2011 Oracle Corporation

QA

Page 12: Java Platform Performance BoF - Aleksey Shipilëv · – 2x2 Intel i5 2.6 Ghz, Ubuntu 10.10 i686, JDK 6u25 • Три варианта эксперимента: – 1 экземпляр

17 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingближе к делу пример

bull Computer Language Benchmark Gamendash httpshootoutaliothdebianorgndash Самый известный полигон для расстрела невинных ног

bull Тест ldquoPiDigitsrdquondash Вычислить первые N цифр в десятичном разложении πndash Вычисляется приближение π специальным рядом

bull Требуется arbitrary precision для представления рациональных членов ряда

ndash Потенциально параллелизуемаndash Две версии Java-теста

bull Текущая использует GNU MP внутренне параллельна 240 строк кода Java + нативные врапперы + GMP

bull Предыдущая использует BigInteger не параллельна 130 строк кода plain Java

18 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingближе к делу пример

bull Метрика время исполненияndash time java -server pidigits 1000

bull ldquoПрогреемrdquo

pidigitsjavasteady public static void main(String[] args) pidigits m = new pidigits(IntegerparseInt(args[0])) for (int i=0 ilt65 ++i) mpidigits(false) mpidigits(true)

19 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingближе к делу пример

bull Метрика время исполненияndash time java -server pidigits 1000

bull ldquoПрогреемrdquo

pidigitsjavasteady public static void main(String[] args) pidigits m = new pidigits(IntegerparseInt(args[0])) for (int i=0 ilt65 ++i) mpidigits(false) mpidigits(true)

20 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingближе к делу пример

bull Метрика время исполненияndash time java -server pidigits 1000

bull ldquoПрогреемrdquo

pidigitsjava public static void main(String[] args) pidigits m = new pidigits(IntegerparseInt(args[0])) for (int i=0 ilt19 ++i) mpidigits(false) mpidigits(true)

pidigitsjavasteady public static void main(String[] args) pidigits m = new pidigits(IntegerparseInt(args[0])) for (int i=0 ilt65 ++i) mpidigits(false) mpidigits(true)

21 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingв век многоядерных систем

bull Обычная платформаndash 2x2 Intel i5 26 Ghz Ubuntu 1010 i686 JDK 6u25

bull Три варианта экспериментаndash 1 экземпляр бенчмарка

bull по ldquoметодологии CLBGrdquo (+ корректный прогрев)

bull GMP будет использовать 1x4=4 потока

bull BI будет использовать 1x1=1 поток

ndash 4 экземпляра бенчмарка

bull чтобы утилизировать все ядра = снормировать на систему

bull GMP будет использовать 4х4=16 потоков

bull BI будет использовать 4x1=4 потока

ndash 16 потоков

bull ради одинаковой нагрузки на OS = снормировать на систему+OS

bull GMP будет использовать 4х4=16 потоков

bull BI будет работать в 16x1=16 потоков

bull Какой из них наиболее релевантен

22 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingа вот и данные

1 экземпляр 4 экземпляра 16 потоков

ldquoGMPrdquo

884[869 899]

1328 [1286 1371]

1328 [1286 1371]

ldquoBigIntegerrdquo

621 [619 624]

1346 [1335 1356]

1434 [1421 1446]

bull Метрика операции в секундуndash 20 итерацийndash [a b] ndash доверительный интервал на 95

24 copy JavaTechDays 2011 Oracle Corporation

Java 7 Java 8что ожидать в области производительности

bull Java 7ndash invokedynamicndash NIO2ndash Concurrency and Collection updates (ForkJoin)ndash XRender pipeline for Java2D (client)

bull Java 8 (или позже)ndash Модульностьndash -выражения (замыкания)ndash Collection updates (filter map reduce)

25 copy JavaTechDays 2011 Oracle Corporation

bull Мешает ли улучшать производительность JVMndash Да поэтому иногда расширяемся

bull invokedynamicbull Модульность

bull Стоит ли расширяться по первому требованию ndash Нет развитие JVMJIT реализация новых методов оптимизации

позволяет получить бОльший выигрышbull Вложенные классыbull Reflection

Обратная совместимость

26 copy JavaTechDays 2011 Oracle Corporation

Solaris

Лучшая ОС для Javaугадайте какая

bull Высокопроизводительный TCPIP стекndash low-latencyndash up to 50 faster

bull DTracendash мониторинг

bull NUMAndash MPO Memory Placement Optimization

bull Large Pagesndash Автоматическая аллокацияndash Разные размеры

27 copy JavaTechDays 2011 Oracle Corporation

hellip and beyondнастройка параметров JVM

bull Что настраиватьndash httpblogssuncomwattresourcejvm-options-listhtml

ndash httpwwworaclecomtechnetworkjavajavasetechvmoptions-jsp-140102html

bull JVM сама подбирает оптимальные параметры своей работыndash Server vs Client ndash Large pages (Solaris)ndash CompressedOops (64-bit VM)

bull Так что же настраиватьndash GCHeap tuningndash -XX+UseNUMA (Solaris Linux)ndash -XX+UseLargePages (Linux Windows)

bull httpwwworaclecomtechnetworkjavajavasetechlargememory-jsp-137182html

bull Не забытьndash Использовать последнюю версию JDK

29 copy JavaTechDays 2011 Oracle Corporation

Concurrencyэлементная база

bull OS Threadingndash мьютексы

bull mutex_lock()mutex_unlock()ndash conditional waits

bull cond_wait()cond_signal()bull WaitForSingleObject

bull Compare-and-Swap (CAS)ndash CAS(x1 x2 x3) = if (x1 == x2) x1 = x3 ndash атомарная операция поддерживаемая в ldquoжелезеrdquo из нескольких

одновременных CASов успешно завершается только одинndash Миф локальный CAS блокирует шину и стоит больше на

многопроцессорных системах ndash Факт глобальный CAS требует трафика на шине

httpblogssuncomdaveentrybiased_locking_in_hotspot

30 copy JavaTechDays 2011 Oracle Corporation

Concurrencyatomics

bull javautilconcurrentAtomicndash обеспечивают атомарные операции над примитивами и указателямиndash альтернатива synchronized или Lockи

bull Трюк в использовании CASаndash Изменение состояния атомика делается при помощи одного CASаndash Чтение состояния не требует CASа

public final int incrementAndGet() for () int current = get() int next = current + 1 if (compareAndSet(current next)) return next

mov ecxedxmov 0x8(ecx)eaxlea 0x8(ecx)edimov eaxecxinc ecxlock cmpxchg ecx(edi)mov $0x0ebxjne [ok]mov $0x1ebxtest ebxebxje [ok]

31 copy JavaTechDays 2011 Oracle Corporation

Concurrencyvolatile

bull Volatile определяет порядок чтения-записей в полеndash Точная семантика определена в Java Memory Model

bull НЕ обеспечивает атомарностиndash Реализуется расстановкой барьеров

bull Какие из них вставятся в код зависит от Hardware Memory Modelbull Эффект барьера зависит от HMM

PUSHL EBPSUB ESP8MOV EBX[ECX + 12]MEMBAR-acquireMEMBAR-releaseINC EBXMOV [ECX + 12]EBXMEMBAR-volatileLOCK ADDL [ESP + 0] 0ADD ESP8POPL EBPTEST PollPageEAXRET

push ebpsub $0x8espmov 0xc(ecx)ebxinc ebxmov ebx0xc(ecx)lock addl $0x0(esp)add $0x8esppop ebptest eax0xb779c000ret

httpgoswegoedudljmmcookbookhtml

32 copy JavaTechDays 2011 Oracle Corporation

Concurrencyvolatile-счётчик

public class VolatileTest

private int counter = 0 private volatile int volatileCounter = 0

GenerateMicroBenchmark public void testOrdinary() counter++

GenerateMicroBenchmark public void testVolatile() volatileCounter++

33 copy JavaTechDays 2011 Oracle Corporation

Concurrencyбесконфликтный volatile-счётчик

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

500000

1000000

1500000

2000000

2500000

3000000

3500000

Thread-local counter performance

ordinary volatile

Threads

op

ss

ec

34 copy JavaTechDays 2011 Oracle Corporation

Concurrencyконфликтный volatile-счётчик

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

100000

200000

300000

400000

500000

600000

700000

800000

900000

Global counter performance

ordinary volatile

Threads

op

ss

ec

35 copy JavaTechDays 2011 Oracle Corporation

Concurrencyintrinsic synchronization

bull synchronized(object) bull 4 состояния

ndash Initbull Начальное ldquoнеопределённоеrdquo состояние

ndash Biasedbull Захватывается одним ldquoвладеющимrdquo потоком нет конфликтовbull Захват владельцем проверка на threadIDbull Захват не-владельцем переход либо в Biased либо в Thin

ndash Thinbull Захватывается несколькими потоками но конфликтов нетbull Захват CASbull Конфликтный захват переход в Fat

ndash Fatbull Захватывается несколькими потоками конфликт на блокировкеbull Вызов примитива синхронизации из ОС

36 copy JavaTechDays 2011 Oracle Corporation

ConcurrencyjavautilconcurrentLock

bull Построены на базе jucAbstractQueueSynchronizerndash Использует атомики

bull CAS

ndash Использует Unsafepark()unpark()

bull интринзики для cond_wait()cond_signal()WaitForSingleObject()

bull ReentrantLockndash По семантике эквивалентен synchronized

bull Рекурсивный захват проверка на threadID

bull Ставит потоки во внутреннюю очередь и делает park()

ndash Non-Fair (default)

bull Не гарантирует отсутствие starvation

bull Barging FIFO (CAS)

bull Лучшая производительность

ndash Fair

bull Гарантирует отсутствие starvation

bull FIFO

bull Честность в обмен на производительностьhttpgeecsoswegoedudlpapersaqspdf

37 copy JavaTechDays 2011 Oracle Corporation

Concurrencyатомарный счётчик

private AtomicInteger atomic = new AtomicInteger() private ReentrantLock lock = new ReentrantLock() private final Object intrinsicLock = new Object() private int primCounter = 0

GenerateMicroBenchmark public void testAtomicInteger() atomicincrementAndGet()

GenerateMicroBenchmark public void testReentrantLock() locklock() primCounter++ lockunlock()

GenerateMicroBenchmark public void testIntrinsicLock() synchronized (intrinsicLock) primCounter++

38 copy JavaTechDays 2011 Oracle Corporation

Concurrencyатомарный счётчик

0 16 32 48 64 80 96 112 128

1000

10000

100000

Atomic Counter Performance

Intrinsic AtomicInteger ReentrantLock

Threads

ops

sec

8x8 CPUs Solaris 6u25

39 copy JavaTechDays 2011 Oracle Corporation

ConcurrencyReentrantLock vs synchronized

bull Семантика одинаковаndash Требования к видимости памяти

ndash Рекурсивный

bull Плюсы jucRLndash Очередь потоков держится на стороне JVM

bull опционально FIFO-политика при захвате-освобождении

bull позволяет быть ldquoчестнымrdquo на любой платформе

ndash Barging FIFO policy

bull lock() может быть сразу удовлетворён даже если в очереди есть потоки

bull сильно улучшает производительность при конфликте блокировок

ndash Допускается несколько Condition

bull Минусы jucRLndash Нет scopeов требуется ручной unlock() через finally

bull Должно быть проще с ARM в JDK7

40 copy JavaTechDays 2011 Oracle Corporation

Concurrencyбесконфликтный захват

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

10000

20000

30000

40000

50000

60000

70000

80000

90000

100000

110000

120000

130000

140000

150000

Uncontended Lock Performance

intrinsic jucReentrantL (non-fair) jucReentrantL (fair)

Threads

op

sse

c

41 copy JavaTechDays 2011 Oracle Corporation

Concurrencyконфликтный захват

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

500

1000

1500

2000

2500

3000

3500

4000

4500

Contended Lock Performance

intrinsic jucReentrantL (non-fair) jucReentrantL (fair)

Threads

op

sse

c

43 copy 2011 JavaTechDays Oracle Corporation

bull hellip естьbull hellip работаетbull hellip работает хорошоbull hellip знает о железе всё

ndash Количество и тип CPUndash Поддерживаемые инcтрукции (SSEx AVX VIS)ndash Топологию памяти (в тч размеры кэшей и их характеристики)

bull hellip знает о приложении много всегоndash Иерархию загруженных классовndash Актуальную статистику создания объектовndash Горячий кодndash Какие ветвления исполнялисьndash Какие значения использовалисьndash Многое другое

bull hellip не боится использовать эти знания для компиляции

JITфакты

44 copy 2011 JavaTechDays Oracle Corporation

JITоптимизации

46 copy 2011 JavaTechDays Oracle Corporation

JITкак писать код

bull Используйте стандартные библиотекиndash Зачем писать собственный стандартный контейнер

bull Используйте высокоуровневый API ndash javautilndash javautilconcurrentndash NIO NIO2ndash вообще библиотеки

bull Код должен правильным и понятнымndash Сначала правильноndash Потом алгоритмически ldquoбыстроrdquondash Код не должен быть JIT-oriented

bull Правильно используйте возможности языкаndash EPIC FAIL штатная передача управления exceptionамиndash FAIL Возврат ldquoисключенияrdquo через return ltкод_ошибкиgtndash FAIL int вместо Enum или boolean

47 copy 2011 JavaTechDays Oracle Corporation

Как получить ассемблерный код метода

ndash Обычным дебаггером )

ndash JVMTI

ndash -XX+PrintAssemblybull httpwikissuncomdisplayHotSpotInternalsPrintAssembly

JITдля любопытных

54 copy JavaTechDays 2011 Oracle Corporation

StartupEclipse

bull Типичная конфигурацияndash 2x2 Intel i5 26 Ghz Ubuntu 1010 i686 JDK 6u25ndash Eclipse JDT (Galileo)

bull Типичные метрикиndash 6000 загруженных классовndash 1000 методов скомпилированоndash 512 Mb зарезервированного пространства в кучеndash 25 Mb кучи использовано после стартапа

bull Известные ldquoпроблемыrdquondash Загрузка и верификация классовndash JIT-компиляция

55 copy JavaTechDays 2011 Oracle Corporation

StartupEclipse

bull Метрика секунд на запуск-завершениеndash Файловые кеши прогреты практически нулевой дисковый IO

default CDS CDS + no-verify

абсолютное время

583 [574 592]

481[473 484]

461[456 474]

загрузка классов

501[491 511]

339[312 366]

301[294 308]

компиляция 051[043 059]

051[044 058]

051[042 060]

56 copy JavaTechDays 2011 Oracle Corporation

Startupдлинные приложения

bull Важно только для коротких приложенийndash Чем дольше работает приложение тем меньше удельные затраты на

загрузку классов и компиляцию

bull Пример 8 часа работает IntelliJ IDEA 10xndash 26600 классов загруженоndash 5315 методов скомпилировано

bull Загрузка классовndash Всего потрачено 202 с ~07 общего времениndash 10 мсек на класс

bull Компиляцияndash Всего потрачено 112 с ~003 общего времениndash 20 мсек на метод

57 copy JavaTechDays 2011 Oracle Corporation

Whats Next

bull Послушать ещёndash JavaOne Moscow (апрель 2011)

bull Проблема со слайдамиndash Найдите нас на конференцииndash Напишите нам письмо

bull Проблема с JDKndash httpopenjdkjavanetndash Задайте вопрос в OpenJDKndash а лучше сделайте патч и дайте его в OpenJDK на review

58 copy JavaTechDays 2011 Oracle Corporation

QA

Page 13: Java Platform Performance BoF - Aleksey Shipilëv · – 2x2 Intel i5 2.6 Ghz, Ubuntu 10.10 i686, JDK 6u25 • Три варианта эксперимента: – 1 экземпляр

18 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingближе к делу пример

bull Метрика время исполненияndash time java -server pidigits 1000

bull ldquoПрогреемrdquo

pidigitsjavasteady public static void main(String[] args) pidigits m = new pidigits(IntegerparseInt(args[0])) for (int i=0 ilt65 ++i) mpidigits(false) mpidigits(true)

19 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingближе к делу пример

bull Метрика время исполненияndash time java -server pidigits 1000

bull ldquoПрогреемrdquo

pidigitsjavasteady public static void main(String[] args) pidigits m = new pidigits(IntegerparseInt(args[0])) for (int i=0 ilt65 ++i) mpidigits(false) mpidigits(true)

20 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingближе к делу пример

bull Метрика время исполненияndash time java -server pidigits 1000

bull ldquoПрогреемrdquo

pidigitsjava public static void main(String[] args) pidigits m = new pidigits(IntegerparseInt(args[0])) for (int i=0 ilt19 ++i) mpidigits(false) mpidigits(true)

pidigitsjavasteady public static void main(String[] args) pidigits m = new pidigits(IntegerparseInt(args[0])) for (int i=0 ilt65 ++i) mpidigits(false) mpidigits(true)

21 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingв век многоядерных систем

bull Обычная платформаndash 2x2 Intel i5 26 Ghz Ubuntu 1010 i686 JDK 6u25

bull Три варианта экспериментаndash 1 экземпляр бенчмарка

bull по ldquoметодологии CLBGrdquo (+ корректный прогрев)

bull GMP будет использовать 1x4=4 потока

bull BI будет использовать 1x1=1 поток

ndash 4 экземпляра бенчмарка

bull чтобы утилизировать все ядра = снормировать на систему

bull GMP будет использовать 4х4=16 потоков

bull BI будет использовать 4x1=4 потока

ndash 16 потоков

bull ради одинаковой нагрузки на OS = снормировать на систему+OS

bull GMP будет использовать 4х4=16 потоков

bull BI будет работать в 16x1=16 потоков

bull Какой из них наиболее релевантен

22 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingа вот и данные

1 экземпляр 4 экземпляра 16 потоков

ldquoGMPrdquo

884[869 899]

1328 [1286 1371]

1328 [1286 1371]

ldquoBigIntegerrdquo

621 [619 624]

1346 [1335 1356]

1434 [1421 1446]

bull Метрика операции в секундуndash 20 итерацийndash [a b] ndash доверительный интервал на 95

24 copy JavaTechDays 2011 Oracle Corporation

Java 7 Java 8что ожидать в области производительности

bull Java 7ndash invokedynamicndash NIO2ndash Concurrency and Collection updates (ForkJoin)ndash XRender pipeline for Java2D (client)

bull Java 8 (или позже)ndash Модульностьndash -выражения (замыкания)ndash Collection updates (filter map reduce)

25 copy JavaTechDays 2011 Oracle Corporation

bull Мешает ли улучшать производительность JVMndash Да поэтому иногда расширяемся

bull invokedynamicbull Модульность

bull Стоит ли расширяться по первому требованию ndash Нет развитие JVMJIT реализация новых методов оптимизации

позволяет получить бОльший выигрышbull Вложенные классыbull Reflection

Обратная совместимость

26 copy JavaTechDays 2011 Oracle Corporation

Solaris

Лучшая ОС для Javaугадайте какая

bull Высокопроизводительный TCPIP стекndash low-latencyndash up to 50 faster

bull DTracendash мониторинг

bull NUMAndash MPO Memory Placement Optimization

bull Large Pagesndash Автоматическая аллокацияndash Разные размеры

27 copy JavaTechDays 2011 Oracle Corporation

hellip and beyondнастройка параметров JVM

bull Что настраиватьndash httpblogssuncomwattresourcejvm-options-listhtml

ndash httpwwworaclecomtechnetworkjavajavasetechvmoptions-jsp-140102html

bull JVM сама подбирает оптимальные параметры своей работыndash Server vs Client ndash Large pages (Solaris)ndash CompressedOops (64-bit VM)

bull Так что же настраиватьndash GCHeap tuningndash -XX+UseNUMA (Solaris Linux)ndash -XX+UseLargePages (Linux Windows)

bull httpwwworaclecomtechnetworkjavajavasetechlargememory-jsp-137182html

bull Не забытьndash Использовать последнюю версию JDK

29 copy JavaTechDays 2011 Oracle Corporation

Concurrencyэлементная база

bull OS Threadingndash мьютексы

bull mutex_lock()mutex_unlock()ndash conditional waits

bull cond_wait()cond_signal()bull WaitForSingleObject

bull Compare-and-Swap (CAS)ndash CAS(x1 x2 x3) = if (x1 == x2) x1 = x3 ndash атомарная операция поддерживаемая в ldquoжелезеrdquo из нескольких

одновременных CASов успешно завершается только одинndash Миф локальный CAS блокирует шину и стоит больше на

многопроцессорных системах ndash Факт глобальный CAS требует трафика на шине

httpblogssuncomdaveentrybiased_locking_in_hotspot

30 copy JavaTechDays 2011 Oracle Corporation

Concurrencyatomics

bull javautilconcurrentAtomicndash обеспечивают атомарные операции над примитивами и указателямиndash альтернатива synchronized или Lockи

bull Трюк в использовании CASаndash Изменение состояния атомика делается при помощи одного CASаndash Чтение состояния не требует CASа

public final int incrementAndGet() for () int current = get() int next = current + 1 if (compareAndSet(current next)) return next

mov ecxedxmov 0x8(ecx)eaxlea 0x8(ecx)edimov eaxecxinc ecxlock cmpxchg ecx(edi)mov $0x0ebxjne [ok]mov $0x1ebxtest ebxebxje [ok]

31 copy JavaTechDays 2011 Oracle Corporation

Concurrencyvolatile

bull Volatile определяет порядок чтения-записей в полеndash Точная семантика определена в Java Memory Model

bull НЕ обеспечивает атомарностиndash Реализуется расстановкой барьеров

bull Какие из них вставятся в код зависит от Hardware Memory Modelbull Эффект барьера зависит от HMM

PUSHL EBPSUB ESP8MOV EBX[ECX + 12]MEMBAR-acquireMEMBAR-releaseINC EBXMOV [ECX + 12]EBXMEMBAR-volatileLOCK ADDL [ESP + 0] 0ADD ESP8POPL EBPTEST PollPageEAXRET

push ebpsub $0x8espmov 0xc(ecx)ebxinc ebxmov ebx0xc(ecx)lock addl $0x0(esp)add $0x8esppop ebptest eax0xb779c000ret

httpgoswegoedudljmmcookbookhtml

32 copy JavaTechDays 2011 Oracle Corporation

Concurrencyvolatile-счётчик

public class VolatileTest

private int counter = 0 private volatile int volatileCounter = 0

GenerateMicroBenchmark public void testOrdinary() counter++

GenerateMicroBenchmark public void testVolatile() volatileCounter++

33 copy JavaTechDays 2011 Oracle Corporation

Concurrencyбесконфликтный volatile-счётчик

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

500000

1000000

1500000

2000000

2500000

3000000

3500000

Thread-local counter performance

ordinary volatile

Threads

op

ss

ec

34 copy JavaTechDays 2011 Oracle Corporation

Concurrencyконфликтный volatile-счётчик

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

100000

200000

300000

400000

500000

600000

700000

800000

900000

Global counter performance

ordinary volatile

Threads

op

ss

ec

35 copy JavaTechDays 2011 Oracle Corporation

Concurrencyintrinsic synchronization

bull synchronized(object) bull 4 состояния

ndash Initbull Начальное ldquoнеопределённоеrdquo состояние

ndash Biasedbull Захватывается одним ldquoвладеющимrdquo потоком нет конфликтовbull Захват владельцем проверка на threadIDbull Захват не-владельцем переход либо в Biased либо в Thin

ndash Thinbull Захватывается несколькими потоками но конфликтов нетbull Захват CASbull Конфликтный захват переход в Fat

ndash Fatbull Захватывается несколькими потоками конфликт на блокировкеbull Вызов примитива синхронизации из ОС

36 copy JavaTechDays 2011 Oracle Corporation

ConcurrencyjavautilconcurrentLock

bull Построены на базе jucAbstractQueueSynchronizerndash Использует атомики

bull CAS

ndash Использует Unsafepark()unpark()

bull интринзики для cond_wait()cond_signal()WaitForSingleObject()

bull ReentrantLockndash По семантике эквивалентен synchronized

bull Рекурсивный захват проверка на threadID

bull Ставит потоки во внутреннюю очередь и делает park()

ndash Non-Fair (default)

bull Не гарантирует отсутствие starvation

bull Barging FIFO (CAS)

bull Лучшая производительность

ndash Fair

bull Гарантирует отсутствие starvation

bull FIFO

bull Честность в обмен на производительностьhttpgeecsoswegoedudlpapersaqspdf

37 copy JavaTechDays 2011 Oracle Corporation

Concurrencyатомарный счётчик

private AtomicInteger atomic = new AtomicInteger() private ReentrantLock lock = new ReentrantLock() private final Object intrinsicLock = new Object() private int primCounter = 0

GenerateMicroBenchmark public void testAtomicInteger() atomicincrementAndGet()

GenerateMicroBenchmark public void testReentrantLock() locklock() primCounter++ lockunlock()

GenerateMicroBenchmark public void testIntrinsicLock() synchronized (intrinsicLock) primCounter++

38 copy JavaTechDays 2011 Oracle Corporation

Concurrencyатомарный счётчик

0 16 32 48 64 80 96 112 128

1000

10000

100000

Atomic Counter Performance

Intrinsic AtomicInteger ReentrantLock

Threads

ops

sec

8x8 CPUs Solaris 6u25

39 copy JavaTechDays 2011 Oracle Corporation

ConcurrencyReentrantLock vs synchronized

bull Семантика одинаковаndash Требования к видимости памяти

ndash Рекурсивный

bull Плюсы jucRLndash Очередь потоков держится на стороне JVM

bull опционально FIFO-политика при захвате-освобождении

bull позволяет быть ldquoчестнымrdquo на любой платформе

ndash Barging FIFO policy

bull lock() может быть сразу удовлетворён даже если в очереди есть потоки

bull сильно улучшает производительность при конфликте блокировок

ndash Допускается несколько Condition

bull Минусы jucRLndash Нет scopeов требуется ручной unlock() через finally

bull Должно быть проще с ARM в JDK7

40 copy JavaTechDays 2011 Oracle Corporation

Concurrencyбесконфликтный захват

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

10000

20000

30000

40000

50000

60000

70000

80000

90000

100000

110000

120000

130000

140000

150000

Uncontended Lock Performance

intrinsic jucReentrantL (non-fair) jucReentrantL (fair)

Threads

op

sse

c

41 copy JavaTechDays 2011 Oracle Corporation

Concurrencyконфликтный захват

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

500

1000

1500

2000

2500

3000

3500

4000

4500

Contended Lock Performance

intrinsic jucReentrantL (non-fair) jucReentrantL (fair)

Threads

op

sse

c

43 copy 2011 JavaTechDays Oracle Corporation

bull hellip естьbull hellip работаетbull hellip работает хорошоbull hellip знает о железе всё

ndash Количество и тип CPUndash Поддерживаемые инcтрукции (SSEx AVX VIS)ndash Топологию памяти (в тч размеры кэшей и их характеристики)

bull hellip знает о приложении много всегоndash Иерархию загруженных классовndash Актуальную статистику создания объектовndash Горячий кодndash Какие ветвления исполнялисьndash Какие значения использовалисьndash Многое другое

bull hellip не боится использовать эти знания для компиляции

JITфакты

44 copy 2011 JavaTechDays Oracle Corporation

JITоптимизации

46 copy 2011 JavaTechDays Oracle Corporation

JITкак писать код

bull Используйте стандартные библиотекиndash Зачем писать собственный стандартный контейнер

bull Используйте высокоуровневый API ndash javautilndash javautilconcurrentndash NIO NIO2ndash вообще библиотеки

bull Код должен правильным и понятнымndash Сначала правильноndash Потом алгоритмически ldquoбыстроrdquondash Код не должен быть JIT-oriented

bull Правильно используйте возможности языкаndash EPIC FAIL штатная передача управления exceptionамиndash FAIL Возврат ldquoисключенияrdquo через return ltкод_ошибкиgtndash FAIL int вместо Enum или boolean

47 copy 2011 JavaTechDays Oracle Corporation

Как получить ассемблерный код метода

ndash Обычным дебаггером )

ndash JVMTI

ndash -XX+PrintAssemblybull httpwikissuncomdisplayHotSpotInternalsPrintAssembly

JITдля любопытных

54 copy JavaTechDays 2011 Oracle Corporation

StartupEclipse

bull Типичная конфигурацияndash 2x2 Intel i5 26 Ghz Ubuntu 1010 i686 JDK 6u25ndash Eclipse JDT (Galileo)

bull Типичные метрикиndash 6000 загруженных классовndash 1000 методов скомпилированоndash 512 Mb зарезервированного пространства в кучеndash 25 Mb кучи использовано после стартапа

bull Известные ldquoпроблемыrdquondash Загрузка и верификация классовndash JIT-компиляция

55 copy JavaTechDays 2011 Oracle Corporation

StartupEclipse

bull Метрика секунд на запуск-завершениеndash Файловые кеши прогреты практически нулевой дисковый IO

default CDS CDS + no-verify

абсолютное время

583 [574 592]

481[473 484]

461[456 474]

загрузка классов

501[491 511]

339[312 366]

301[294 308]

компиляция 051[043 059]

051[044 058]

051[042 060]

56 copy JavaTechDays 2011 Oracle Corporation

Startupдлинные приложения

bull Важно только для коротких приложенийndash Чем дольше работает приложение тем меньше удельные затраты на

загрузку классов и компиляцию

bull Пример 8 часа работает IntelliJ IDEA 10xndash 26600 классов загруженоndash 5315 методов скомпилировано

bull Загрузка классовndash Всего потрачено 202 с ~07 общего времениndash 10 мсек на класс

bull Компиляцияndash Всего потрачено 112 с ~003 общего времениndash 20 мсек на метод

57 copy JavaTechDays 2011 Oracle Corporation

Whats Next

bull Послушать ещёndash JavaOne Moscow (апрель 2011)

bull Проблема со слайдамиndash Найдите нас на конференцииndash Напишите нам письмо

bull Проблема с JDKndash httpopenjdkjavanetndash Задайте вопрос в OpenJDKndash а лучше сделайте патч и дайте его в OpenJDK на review

58 copy JavaTechDays 2011 Oracle Corporation

QA

Page 14: Java Platform Performance BoF - Aleksey Shipilëv · – 2x2 Intel i5 2.6 Ghz, Ubuntu 10.10 i686, JDK 6u25 • Три варианта эксперимента: – 1 экземпляр

19 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingближе к делу пример

bull Метрика время исполненияndash time java -server pidigits 1000

bull ldquoПрогреемrdquo

pidigitsjavasteady public static void main(String[] args) pidigits m = new pidigits(IntegerparseInt(args[0])) for (int i=0 ilt65 ++i) mpidigits(false) mpidigits(true)

20 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingближе к делу пример

bull Метрика время исполненияndash time java -server pidigits 1000

bull ldquoПрогреемrdquo

pidigitsjava public static void main(String[] args) pidigits m = new pidigits(IntegerparseInt(args[0])) for (int i=0 ilt19 ++i) mpidigits(false) mpidigits(true)

pidigitsjavasteady public static void main(String[] args) pidigits m = new pidigits(IntegerparseInt(args[0])) for (int i=0 ilt65 ++i) mpidigits(false) mpidigits(true)

21 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingв век многоядерных систем

bull Обычная платформаndash 2x2 Intel i5 26 Ghz Ubuntu 1010 i686 JDK 6u25

bull Три варианта экспериментаndash 1 экземпляр бенчмарка

bull по ldquoметодологии CLBGrdquo (+ корректный прогрев)

bull GMP будет использовать 1x4=4 потока

bull BI будет использовать 1x1=1 поток

ndash 4 экземпляра бенчмарка

bull чтобы утилизировать все ядра = снормировать на систему

bull GMP будет использовать 4х4=16 потоков

bull BI будет использовать 4x1=4 потока

ndash 16 потоков

bull ради одинаковой нагрузки на OS = снормировать на систему+OS

bull GMP будет использовать 4х4=16 потоков

bull BI будет работать в 16x1=16 потоков

bull Какой из них наиболее релевантен

22 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingа вот и данные

1 экземпляр 4 экземпляра 16 потоков

ldquoGMPrdquo

884[869 899]

1328 [1286 1371]

1328 [1286 1371]

ldquoBigIntegerrdquo

621 [619 624]

1346 [1335 1356]

1434 [1421 1446]

bull Метрика операции в секундуndash 20 итерацийndash [a b] ndash доверительный интервал на 95

24 copy JavaTechDays 2011 Oracle Corporation

Java 7 Java 8что ожидать в области производительности

bull Java 7ndash invokedynamicndash NIO2ndash Concurrency and Collection updates (ForkJoin)ndash XRender pipeline for Java2D (client)

bull Java 8 (или позже)ndash Модульностьndash -выражения (замыкания)ndash Collection updates (filter map reduce)

25 copy JavaTechDays 2011 Oracle Corporation

bull Мешает ли улучшать производительность JVMndash Да поэтому иногда расширяемся

bull invokedynamicbull Модульность

bull Стоит ли расширяться по первому требованию ndash Нет развитие JVMJIT реализация новых методов оптимизации

позволяет получить бОльший выигрышbull Вложенные классыbull Reflection

Обратная совместимость

26 copy JavaTechDays 2011 Oracle Corporation

Solaris

Лучшая ОС для Javaугадайте какая

bull Высокопроизводительный TCPIP стекndash low-latencyndash up to 50 faster

bull DTracendash мониторинг

bull NUMAndash MPO Memory Placement Optimization

bull Large Pagesndash Автоматическая аллокацияndash Разные размеры

27 copy JavaTechDays 2011 Oracle Corporation

hellip and beyondнастройка параметров JVM

bull Что настраиватьndash httpblogssuncomwattresourcejvm-options-listhtml

ndash httpwwworaclecomtechnetworkjavajavasetechvmoptions-jsp-140102html

bull JVM сама подбирает оптимальные параметры своей работыndash Server vs Client ndash Large pages (Solaris)ndash CompressedOops (64-bit VM)

bull Так что же настраиватьndash GCHeap tuningndash -XX+UseNUMA (Solaris Linux)ndash -XX+UseLargePages (Linux Windows)

bull httpwwworaclecomtechnetworkjavajavasetechlargememory-jsp-137182html

bull Не забытьndash Использовать последнюю версию JDK

29 copy JavaTechDays 2011 Oracle Corporation

Concurrencyэлементная база

bull OS Threadingndash мьютексы

bull mutex_lock()mutex_unlock()ndash conditional waits

bull cond_wait()cond_signal()bull WaitForSingleObject

bull Compare-and-Swap (CAS)ndash CAS(x1 x2 x3) = if (x1 == x2) x1 = x3 ndash атомарная операция поддерживаемая в ldquoжелезеrdquo из нескольких

одновременных CASов успешно завершается только одинndash Миф локальный CAS блокирует шину и стоит больше на

многопроцессорных системах ndash Факт глобальный CAS требует трафика на шине

httpblogssuncomdaveentrybiased_locking_in_hotspot

30 copy JavaTechDays 2011 Oracle Corporation

Concurrencyatomics

bull javautilconcurrentAtomicndash обеспечивают атомарные операции над примитивами и указателямиndash альтернатива synchronized или Lockи

bull Трюк в использовании CASаndash Изменение состояния атомика делается при помощи одного CASаndash Чтение состояния не требует CASа

public final int incrementAndGet() for () int current = get() int next = current + 1 if (compareAndSet(current next)) return next

mov ecxedxmov 0x8(ecx)eaxlea 0x8(ecx)edimov eaxecxinc ecxlock cmpxchg ecx(edi)mov $0x0ebxjne [ok]mov $0x1ebxtest ebxebxje [ok]

31 copy JavaTechDays 2011 Oracle Corporation

Concurrencyvolatile

bull Volatile определяет порядок чтения-записей в полеndash Точная семантика определена в Java Memory Model

bull НЕ обеспечивает атомарностиndash Реализуется расстановкой барьеров

bull Какие из них вставятся в код зависит от Hardware Memory Modelbull Эффект барьера зависит от HMM

PUSHL EBPSUB ESP8MOV EBX[ECX + 12]MEMBAR-acquireMEMBAR-releaseINC EBXMOV [ECX + 12]EBXMEMBAR-volatileLOCK ADDL [ESP + 0] 0ADD ESP8POPL EBPTEST PollPageEAXRET

push ebpsub $0x8espmov 0xc(ecx)ebxinc ebxmov ebx0xc(ecx)lock addl $0x0(esp)add $0x8esppop ebptest eax0xb779c000ret

httpgoswegoedudljmmcookbookhtml

32 copy JavaTechDays 2011 Oracle Corporation

Concurrencyvolatile-счётчик

public class VolatileTest

private int counter = 0 private volatile int volatileCounter = 0

GenerateMicroBenchmark public void testOrdinary() counter++

GenerateMicroBenchmark public void testVolatile() volatileCounter++

33 copy JavaTechDays 2011 Oracle Corporation

Concurrencyбесконфликтный volatile-счётчик

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

500000

1000000

1500000

2000000

2500000

3000000

3500000

Thread-local counter performance

ordinary volatile

Threads

op

ss

ec

34 copy JavaTechDays 2011 Oracle Corporation

Concurrencyконфликтный volatile-счётчик

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

100000

200000

300000

400000

500000

600000

700000

800000

900000

Global counter performance

ordinary volatile

Threads

op

ss

ec

35 copy JavaTechDays 2011 Oracle Corporation

Concurrencyintrinsic synchronization

bull synchronized(object) bull 4 состояния

ndash Initbull Начальное ldquoнеопределённоеrdquo состояние

ndash Biasedbull Захватывается одним ldquoвладеющимrdquo потоком нет конфликтовbull Захват владельцем проверка на threadIDbull Захват не-владельцем переход либо в Biased либо в Thin

ndash Thinbull Захватывается несколькими потоками но конфликтов нетbull Захват CASbull Конфликтный захват переход в Fat

ndash Fatbull Захватывается несколькими потоками конфликт на блокировкеbull Вызов примитива синхронизации из ОС

36 copy JavaTechDays 2011 Oracle Corporation

ConcurrencyjavautilconcurrentLock

bull Построены на базе jucAbstractQueueSynchronizerndash Использует атомики

bull CAS

ndash Использует Unsafepark()unpark()

bull интринзики для cond_wait()cond_signal()WaitForSingleObject()

bull ReentrantLockndash По семантике эквивалентен synchronized

bull Рекурсивный захват проверка на threadID

bull Ставит потоки во внутреннюю очередь и делает park()

ndash Non-Fair (default)

bull Не гарантирует отсутствие starvation

bull Barging FIFO (CAS)

bull Лучшая производительность

ndash Fair

bull Гарантирует отсутствие starvation

bull FIFO

bull Честность в обмен на производительностьhttpgeecsoswegoedudlpapersaqspdf

37 copy JavaTechDays 2011 Oracle Corporation

Concurrencyатомарный счётчик

private AtomicInteger atomic = new AtomicInteger() private ReentrantLock lock = new ReentrantLock() private final Object intrinsicLock = new Object() private int primCounter = 0

GenerateMicroBenchmark public void testAtomicInteger() atomicincrementAndGet()

GenerateMicroBenchmark public void testReentrantLock() locklock() primCounter++ lockunlock()

GenerateMicroBenchmark public void testIntrinsicLock() synchronized (intrinsicLock) primCounter++

38 copy JavaTechDays 2011 Oracle Corporation

Concurrencyатомарный счётчик

0 16 32 48 64 80 96 112 128

1000

10000

100000

Atomic Counter Performance

Intrinsic AtomicInteger ReentrantLock

Threads

ops

sec

8x8 CPUs Solaris 6u25

39 copy JavaTechDays 2011 Oracle Corporation

ConcurrencyReentrantLock vs synchronized

bull Семантика одинаковаndash Требования к видимости памяти

ndash Рекурсивный

bull Плюсы jucRLndash Очередь потоков держится на стороне JVM

bull опционально FIFO-политика при захвате-освобождении

bull позволяет быть ldquoчестнымrdquo на любой платформе

ndash Barging FIFO policy

bull lock() может быть сразу удовлетворён даже если в очереди есть потоки

bull сильно улучшает производительность при конфликте блокировок

ndash Допускается несколько Condition

bull Минусы jucRLndash Нет scopeов требуется ручной unlock() через finally

bull Должно быть проще с ARM в JDK7

40 copy JavaTechDays 2011 Oracle Corporation

Concurrencyбесконфликтный захват

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

10000

20000

30000

40000

50000

60000

70000

80000

90000

100000

110000

120000

130000

140000

150000

Uncontended Lock Performance

intrinsic jucReentrantL (non-fair) jucReentrantL (fair)

Threads

op

sse

c

41 copy JavaTechDays 2011 Oracle Corporation

Concurrencyконфликтный захват

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

500

1000

1500

2000

2500

3000

3500

4000

4500

Contended Lock Performance

intrinsic jucReentrantL (non-fair) jucReentrantL (fair)

Threads

op

sse

c

43 copy 2011 JavaTechDays Oracle Corporation

bull hellip естьbull hellip работаетbull hellip работает хорошоbull hellip знает о железе всё

ndash Количество и тип CPUndash Поддерживаемые инcтрукции (SSEx AVX VIS)ndash Топологию памяти (в тч размеры кэшей и их характеристики)

bull hellip знает о приложении много всегоndash Иерархию загруженных классовndash Актуальную статистику создания объектовndash Горячий кодndash Какие ветвления исполнялисьndash Какие значения использовалисьndash Многое другое

bull hellip не боится использовать эти знания для компиляции

JITфакты

44 copy 2011 JavaTechDays Oracle Corporation

JITоптимизации

46 copy 2011 JavaTechDays Oracle Corporation

JITкак писать код

bull Используйте стандартные библиотекиndash Зачем писать собственный стандартный контейнер

bull Используйте высокоуровневый API ndash javautilndash javautilconcurrentndash NIO NIO2ndash вообще библиотеки

bull Код должен правильным и понятнымndash Сначала правильноndash Потом алгоритмически ldquoбыстроrdquondash Код не должен быть JIT-oriented

bull Правильно используйте возможности языкаndash EPIC FAIL штатная передача управления exceptionамиndash FAIL Возврат ldquoисключенияrdquo через return ltкод_ошибкиgtndash FAIL int вместо Enum или boolean

47 copy 2011 JavaTechDays Oracle Corporation

Как получить ассемблерный код метода

ndash Обычным дебаггером )

ndash JVMTI

ndash -XX+PrintAssemblybull httpwikissuncomdisplayHotSpotInternalsPrintAssembly

JITдля любопытных

54 copy JavaTechDays 2011 Oracle Corporation

StartupEclipse

bull Типичная конфигурацияndash 2x2 Intel i5 26 Ghz Ubuntu 1010 i686 JDK 6u25ndash Eclipse JDT (Galileo)

bull Типичные метрикиndash 6000 загруженных классовndash 1000 методов скомпилированоndash 512 Mb зарезервированного пространства в кучеndash 25 Mb кучи использовано после стартапа

bull Известные ldquoпроблемыrdquondash Загрузка и верификация классовndash JIT-компиляция

55 copy JavaTechDays 2011 Oracle Corporation

StartupEclipse

bull Метрика секунд на запуск-завершениеndash Файловые кеши прогреты практически нулевой дисковый IO

default CDS CDS + no-verify

абсолютное время

583 [574 592]

481[473 484]

461[456 474]

загрузка классов

501[491 511]

339[312 366]

301[294 308]

компиляция 051[043 059]

051[044 058]

051[042 060]

56 copy JavaTechDays 2011 Oracle Corporation

Startupдлинные приложения

bull Важно только для коротких приложенийndash Чем дольше работает приложение тем меньше удельные затраты на

загрузку классов и компиляцию

bull Пример 8 часа работает IntelliJ IDEA 10xndash 26600 классов загруженоndash 5315 методов скомпилировано

bull Загрузка классовndash Всего потрачено 202 с ~07 общего времениndash 10 мсек на класс

bull Компиляцияndash Всего потрачено 112 с ~003 общего времениndash 20 мсек на метод

57 copy JavaTechDays 2011 Oracle Corporation

Whats Next

bull Послушать ещёndash JavaOne Moscow (апрель 2011)

bull Проблема со слайдамиndash Найдите нас на конференцииndash Напишите нам письмо

bull Проблема с JDKndash httpopenjdkjavanetndash Задайте вопрос в OpenJDKndash а лучше сделайте патч и дайте его в OpenJDK на review

58 copy JavaTechDays 2011 Oracle Corporation

QA

Page 15: Java Platform Performance BoF - Aleksey Shipilëv · – 2x2 Intel i5 2.6 Ghz, Ubuntu 10.10 i686, JDK 6u25 • Три варианта эксперимента: – 1 экземпляр

20 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingближе к делу пример

bull Метрика время исполненияndash time java -server pidigits 1000

bull ldquoПрогреемrdquo

pidigitsjava public static void main(String[] args) pidigits m = new pidigits(IntegerparseInt(args[0])) for (int i=0 ilt19 ++i) mpidigits(false) mpidigits(true)

pidigitsjavasteady public static void main(String[] args) pidigits m = new pidigits(IntegerparseInt(args[0])) for (int i=0 ilt65 ++i) mpidigits(false) mpidigits(true)

21 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingв век многоядерных систем

bull Обычная платформаndash 2x2 Intel i5 26 Ghz Ubuntu 1010 i686 JDK 6u25

bull Три варианта экспериментаndash 1 экземпляр бенчмарка

bull по ldquoметодологии CLBGrdquo (+ корректный прогрев)

bull GMP будет использовать 1x4=4 потока

bull BI будет использовать 1x1=1 поток

ndash 4 экземпляра бенчмарка

bull чтобы утилизировать все ядра = снормировать на систему

bull GMP будет использовать 4х4=16 потоков

bull BI будет использовать 4x1=4 потока

ndash 16 потоков

bull ради одинаковой нагрузки на OS = снормировать на систему+OS

bull GMP будет использовать 4х4=16 потоков

bull BI будет работать в 16x1=16 потоков

bull Какой из них наиболее релевантен

22 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingа вот и данные

1 экземпляр 4 экземпляра 16 потоков

ldquoGMPrdquo

884[869 899]

1328 [1286 1371]

1328 [1286 1371]

ldquoBigIntegerrdquo

621 [619 624]

1346 [1335 1356]

1434 [1421 1446]

bull Метрика операции в секундуndash 20 итерацийndash [a b] ndash доверительный интервал на 95

24 copy JavaTechDays 2011 Oracle Corporation

Java 7 Java 8что ожидать в области производительности

bull Java 7ndash invokedynamicndash NIO2ndash Concurrency and Collection updates (ForkJoin)ndash XRender pipeline for Java2D (client)

bull Java 8 (или позже)ndash Модульностьndash -выражения (замыкания)ndash Collection updates (filter map reduce)

25 copy JavaTechDays 2011 Oracle Corporation

bull Мешает ли улучшать производительность JVMndash Да поэтому иногда расширяемся

bull invokedynamicbull Модульность

bull Стоит ли расширяться по первому требованию ndash Нет развитие JVMJIT реализация новых методов оптимизации

позволяет получить бОльший выигрышbull Вложенные классыbull Reflection

Обратная совместимость

26 copy JavaTechDays 2011 Oracle Corporation

Solaris

Лучшая ОС для Javaугадайте какая

bull Высокопроизводительный TCPIP стекndash low-latencyndash up to 50 faster

bull DTracendash мониторинг

bull NUMAndash MPO Memory Placement Optimization

bull Large Pagesndash Автоматическая аллокацияndash Разные размеры

27 copy JavaTechDays 2011 Oracle Corporation

hellip and beyondнастройка параметров JVM

bull Что настраиватьndash httpblogssuncomwattresourcejvm-options-listhtml

ndash httpwwworaclecomtechnetworkjavajavasetechvmoptions-jsp-140102html

bull JVM сама подбирает оптимальные параметры своей работыndash Server vs Client ndash Large pages (Solaris)ndash CompressedOops (64-bit VM)

bull Так что же настраиватьndash GCHeap tuningndash -XX+UseNUMA (Solaris Linux)ndash -XX+UseLargePages (Linux Windows)

bull httpwwworaclecomtechnetworkjavajavasetechlargememory-jsp-137182html

bull Не забытьndash Использовать последнюю версию JDK

29 copy JavaTechDays 2011 Oracle Corporation

Concurrencyэлементная база

bull OS Threadingndash мьютексы

bull mutex_lock()mutex_unlock()ndash conditional waits

bull cond_wait()cond_signal()bull WaitForSingleObject

bull Compare-and-Swap (CAS)ndash CAS(x1 x2 x3) = if (x1 == x2) x1 = x3 ndash атомарная операция поддерживаемая в ldquoжелезеrdquo из нескольких

одновременных CASов успешно завершается только одинndash Миф локальный CAS блокирует шину и стоит больше на

многопроцессорных системах ndash Факт глобальный CAS требует трафика на шине

httpblogssuncomdaveentrybiased_locking_in_hotspot

30 copy JavaTechDays 2011 Oracle Corporation

Concurrencyatomics

bull javautilconcurrentAtomicndash обеспечивают атомарные операции над примитивами и указателямиndash альтернатива synchronized или Lockи

bull Трюк в использовании CASаndash Изменение состояния атомика делается при помощи одного CASаndash Чтение состояния не требует CASа

public final int incrementAndGet() for () int current = get() int next = current + 1 if (compareAndSet(current next)) return next

mov ecxedxmov 0x8(ecx)eaxlea 0x8(ecx)edimov eaxecxinc ecxlock cmpxchg ecx(edi)mov $0x0ebxjne [ok]mov $0x1ebxtest ebxebxje [ok]

31 copy JavaTechDays 2011 Oracle Corporation

Concurrencyvolatile

bull Volatile определяет порядок чтения-записей в полеndash Точная семантика определена в Java Memory Model

bull НЕ обеспечивает атомарностиndash Реализуется расстановкой барьеров

bull Какие из них вставятся в код зависит от Hardware Memory Modelbull Эффект барьера зависит от HMM

PUSHL EBPSUB ESP8MOV EBX[ECX + 12]MEMBAR-acquireMEMBAR-releaseINC EBXMOV [ECX + 12]EBXMEMBAR-volatileLOCK ADDL [ESP + 0] 0ADD ESP8POPL EBPTEST PollPageEAXRET

push ebpsub $0x8espmov 0xc(ecx)ebxinc ebxmov ebx0xc(ecx)lock addl $0x0(esp)add $0x8esppop ebptest eax0xb779c000ret

httpgoswegoedudljmmcookbookhtml

32 copy JavaTechDays 2011 Oracle Corporation

Concurrencyvolatile-счётчик

public class VolatileTest

private int counter = 0 private volatile int volatileCounter = 0

GenerateMicroBenchmark public void testOrdinary() counter++

GenerateMicroBenchmark public void testVolatile() volatileCounter++

33 copy JavaTechDays 2011 Oracle Corporation

Concurrencyбесконфликтный volatile-счётчик

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

500000

1000000

1500000

2000000

2500000

3000000

3500000

Thread-local counter performance

ordinary volatile

Threads

op

ss

ec

34 copy JavaTechDays 2011 Oracle Corporation

Concurrencyконфликтный volatile-счётчик

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

100000

200000

300000

400000

500000

600000

700000

800000

900000

Global counter performance

ordinary volatile

Threads

op

ss

ec

35 copy JavaTechDays 2011 Oracle Corporation

Concurrencyintrinsic synchronization

bull synchronized(object) bull 4 состояния

ndash Initbull Начальное ldquoнеопределённоеrdquo состояние

ndash Biasedbull Захватывается одним ldquoвладеющимrdquo потоком нет конфликтовbull Захват владельцем проверка на threadIDbull Захват не-владельцем переход либо в Biased либо в Thin

ndash Thinbull Захватывается несколькими потоками но конфликтов нетbull Захват CASbull Конфликтный захват переход в Fat

ndash Fatbull Захватывается несколькими потоками конфликт на блокировкеbull Вызов примитива синхронизации из ОС

36 copy JavaTechDays 2011 Oracle Corporation

ConcurrencyjavautilconcurrentLock

bull Построены на базе jucAbstractQueueSynchronizerndash Использует атомики

bull CAS

ndash Использует Unsafepark()unpark()

bull интринзики для cond_wait()cond_signal()WaitForSingleObject()

bull ReentrantLockndash По семантике эквивалентен synchronized

bull Рекурсивный захват проверка на threadID

bull Ставит потоки во внутреннюю очередь и делает park()

ndash Non-Fair (default)

bull Не гарантирует отсутствие starvation

bull Barging FIFO (CAS)

bull Лучшая производительность

ndash Fair

bull Гарантирует отсутствие starvation

bull FIFO

bull Честность в обмен на производительностьhttpgeecsoswegoedudlpapersaqspdf

37 copy JavaTechDays 2011 Oracle Corporation

Concurrencyатомарный счётчик

private AtomicInteger atomic = new AtomicInteger() private ReentrantLock lock = new ReentrantLock() private final Object intrinsicLock = new Object() private int primCounter = 0

GenerateMicroBenchmark public void testAtomicInteger() atomicincrementAndGet()

GenerateMicroBenchmark public void testReentrantLock() locklock() primCounter++ lockunlock()

GenerateMicroBenchmark public void testIntrinsicLock() synchronized (intrinsicLock) primCounter++

38 copy JavaTechDays 2011 Oracle Corporation

Concurrencyатомарный счётчик

0 16 32 48 64 80 96 112 128

1000

10000

100000

Atomic Counter Performance

Intrinsic AtomicInteger ReentrantLock

Threads

ops

sec

8x8 CPUs Solaris 6u25

39 copy JavaTechDays 2011 Oracle Corporation

ConcurrencyReentrantLock vs synchronized

bull Семантика одинаковаndash Требования к видимости памяти

ndash Рекурсивный

bull Плюсы jucRLndash Очередь потоков держится на стороне JVM

bull опционально FIFO-политика при захвате-освобождении

bull позволяет быть ldquoчестнымrdquo на любой платформе

ndash Barging FIFO policy

bull lock() может быть сразу удовлетворён даже если в очереди есть потоки

bull сильно улучшает производительность при конфликте блокировок

ndash Допускается несколько Condition

bull Минусы jucRLndash Нет scopeов требуется ручной unlock() через finally

bull Должно быть проще с ARM в JDK7

40 copy JavaTechDays 2011 Oracle Corporation

Concurrencyбесконфликтный захват

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

10000

20000

30000

40000

50000

60000

70000

80000

90000

100000

110000

120000

130000

140000

150000

Uncontended Lock Performance

intrinsic jucReentrantL (non-fair) jucReentrantL (fair)

Threads

op

sse

c

41 copy JavaTechDays 2011 Oracle Corporation

Concurrencyконфликтный захват

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

500

1000

1500

2000

2500

3000

3500

4000

4500

Contended Lock Performance

intrinsic jucReentrantL (non-fair) jucReentrantL (fair)

Threads

op

sse

c

43 copy 2011 JavaTechDays Oracle Corporation

bull hellip естьbull hellip работаетbull hellip работает хорошоbull hellip знает о железе всё

ndash Количество и тип CPUndash Поддерживаемые инcтрукции (SSEx AVX VIS)ndash Топологию памяти (в тч размеры кэшей и их характеристики)

bull hellip знает о приложении много всегоndash Иерархию загруженных классовndash Актуальную статистику создания объектовndash Горячий кодndash Какие ветвления исполнялисьndash Какие значения использовалисьndash Многое другое

bull hellip не боится использовать эти знания для компиляции

JITфакты

44 copy 2011 JavaTechDays Oracle Corporation

JITоптимизации

46 copy 2011 JavaTechDays Oracle Corporation

JITкак писать код

bull Используйте стандартные библиотекиndash Зачем писать собственный стандартный контейнер

bull Используйте высокоуровневый API ndash javautilndash javautilconcurrentndash NIO NIO2ndash вообще библиотеки

bull Код должен правильным и понятнымndash Сначала правильноndash Потом алгоритмически ldquoбыстроrdquondash Код не должен быть JIT-oriented

bull Правильно используйте возможности языкаndash EPIC FAIL штатная передача управления exceptionамиndash FAIL Возврат ldquoисключенияrdquo через return ltкод_ошибкиgtndash FAIL int вместо Enum или boolean

47 copy 2011 JavaTechDays Oracle Corporation

Как получить ассемблерный код метода

ndash Обычным дебаггером )

ndash JVMTI

ndash -XX+PrintAssemblybull httpwikissuncomdisplayHotSpotInternalsPrintAssembly

JITдля любопытных

54 copy JavaTechDays 2011 Oracle Corporation

StartupEclipse

bull Типичная конфигурацияndash 2x2 Intel i5 26 Ghz Ubuntu 1010 i686 JDK 6u25ndash Eclipse JDT (Galileo)

bull Типичные метрикиndash 6000 загруженных классовndash 1000 методов скомпилированоndash 512 Mb зарезервированного пространства в кучеndash 25 Mb кучи использовано после стартапа

bull Известные ldquoпроблемыrdquondash Загрузка и верификация классовndash JIT-компиляция

55 copy JavaTechDays 2011 Oracle Corporation

StartupEclipse

bull Метрика секунд на запуск-завершениеndash Файловые кеши прогреты практически нулевой дисковый IO

default CDS CDS + no-verify

абсолютное время

583 [574 592]

481[473 484]

461[456 474]

загрузка классов

501[491 511]

339[312 366]

301[294 308]

компиляция 051[043 059]

051[044 058]

051[042 060]

56 copy JavaTechDays 2011 Oracle Corporation

Startupдлинные приложения

bull Важно только для коротких приложенийndash Чем дольше работает приложение тем меньше удельные затраты на

загрузку классов и компиляцию

bull Пример 8 часа работает IntelliJ IDEA 10xndash 26600 классов загруженоndash 5315 методов скомпилировано

bull Загрузка классовndash Всего потрачено 202 с ~07 общего времениndash 10 мсек на класс

bull Компиляцияndash Всего потрачено 112 с ~003 общего времениndash 20 мсек на метод

57 copy JavaTechDays 2011 Oracle Corporation

Whats Next

bull Послушать ещёndash JavaOne Moscow (апрель 2011)

bull Проблема со слайдамиndash Найдите нас на конференцииndash Напишите нам письмо

bull Проблема с JDKndash httpopenjdkjavanetndash Задайте вопрос в OpenJDKndash а лучше сделайте патч и дайте его в OpenJDK на review

58 copy JavaTechDays 2011 Oracle Corporation

QA

Page 16: Java Platform Performance BoF - Aleksey Shipilëv · – 2x2 Intel i5 2.6 Ghz, Ubuntu 10.10 i686, JDK 6u25 • Три варианта эксперимента: – 1 экземпляр

21 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingв век многоядерных систем

bull Обычная платформаndash 2x2 Intel i5 26 Ghz Ubuntu 1010 i686 JDK 6u25

bull Три варианта экспериментаndash 1 экземпляр бенчмарка

bull по ldquoметодологии CLBGrdquo (+ корректный прогрев)

bull GMP будет использовать 1x4=4 потока

bull BI будет использовать 1x1=1 поток

ndash 4 экземпляра бенчмарка

bull чтобы утилизировать все ядра = снормировать на систему

bull GMP будет использовать 4х4=16 потоков

bull BI будет использовать 4x1=4 потока

ndash 16 потоков

bull ради одинаковой нагрузки на OS = снормировать на систему+OS

bull GMP будет использовать 4х4=16 потоков

bull BI будет работать в 16x1=16 потоков

bull Какой из них наиболее релевантен

22 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingа вот и данные

1 экземпляр 4 экземпляра 16 потоков

ldquoGMPrdquo

884[869 899]

1328 [1286 1371]

1328 [1286 1371]

ldquoBigIntegerrdquo

621 [619 624]

1346 [1335 1356]

1434 [1421 1446]

bull Метрика операции в секундуndash 20 итерацийndash [a b] ndash доверительный интервал на 95

24 copy JavaTechDays 2011 Oracle Corporation

Java 7 Java 8что ожидать в области производительности

bull Java 7ndash invokedynamicndash NIO2ndash Concurrency and Collection updates (ForkJoin)ndash XRender pipeline for Java2D (client)

bull Java 8 (или позже)ndash Модульностьndash -выражения (замыкания)ndash Collection updates (filter map reduce)

25 copy JavaTechDays 2011 Oracle Corporation

bull Мешает ли улучшать производительность JVMndash Да поэтому иногда расширяемся

bull invokedynamicbull Модульность

bull Стоит ли расширяться по первому требованию ndash Нет развитие JVMJIT реализация новых методов оптимизации

позволяет получить бОльший выигрышbull Вложенные классыbull Reflection

Обратная совместимость

26 copy JavaTechDays 2011 Oracle Corporation

Solaris

Лучшая ОС для Javaугадайте какая

bull Высокопроизводительный TCPIP стекndash low-latencyndash up to 50 faster

bull DTracendash мониторинг

bull NUMAndash MPO Memory Placement Optimization

bull Large Pagesndash Автоматическая аллокацияndash Разные размеры

27 copy JavaTechDays 2011 Oracle Corporation

hellip and beyondнастройка параметров JVM

bull Что настраиватьndash httpblogssuncomwattresourcejvm-options-listhtml

ndash httpwwworaclecomtechnetworkjavajavasetechvmoptions-jsp-140102html

bull JVM сама подбирает оптимальные параметры своей работыndash Server vs Client ndash Large pages (Solaris)ndash CompressedOops (64-bit VM)

bull Так что же настраиватьndash GCHeap tuningndash -XX+UseNUMA (Solaris Linux)ndash -XX+UseLargePages (Linux Windows)

bull httpwwworaclecomtechnetworkjavajavasetechlargememory-jsp-137182html

bull Не забытьndash Использовать последнюю версию JDK

29 copy JavaTechDays 2011 Oracle Corporation

Concurrencyэлементная база

bull OS Threadingndash мьютексы

bull mutex_lock()mutex_unlock()ndash conditional waits

bull cond_wait()cond_signal()bull WaitForSingleObject

bull Compare-and-Swap (CAS)ndash CAS(x1 x2 x3) = if (x1 == x2) x1 = x3 ndash атомарная операция поддерживаемая в ldquoжелезеrdquo из нескольких

одновременных CASов успешно завершается только одинndash Миф локальный CAS блокирует шину и стоит больше на

многопроцессорных системах ndash Факт глобальный CAS требует трафика на шине

httpblogssuncomdaveentrybiased_locking_in_hotspot

30 copy JavaTechDays 2011 Oracle Corporation

Concurrencyatomics

bull javautilconcurrentAtomicndash обеспечивают атомарные операции над примитивами и указателямиndash альтернатива synchronized или Lockи

bull Трюк в использовании CASаndash Изменение состояния атомика делается при помощи одного CASаndash Чтение состояния не требует CASа

public final int incrementAndGet() for () int current = get() int next = current + 1 if (compareAndSet(current next)) return next

mov ecxedxmov 0x8(ecx)eaxlea 0x8(ecx)edimov eaxecxinc ecxlock cmpxchg ecx(edi)mov $0x0ebxjne [ok]mov $0x1ebxtest ebxebxje [ok]

31 copy JavaTechDays 2011 Oracle Corporation

Concurrencyvolatile

bull Volatile определяет порядок чтения-записей в полеndash Точная семантика определена в Java Memory Model

bull НЕ обеспечивает атомарностиndash Реализуется расстановкой барьеров

bull Какие из них вставятся в код зависит от Hardware Memory Modelbull Эффект барьера зависит от HMM

PUSHL EBPSUB ESP8MOV EBX[ECX + 12]MEMBAR-acquireMEMBAR-releaseINC EBXMOV [ECX + 12]EBXMEMBAR-volatileLOCK ADDL [ESP + 0] 0ADD ESP8POPL EBPTEST PollPageEAXRET

push ebpsub $0x8espmov 0xc(ecx)ebxinc ebxmov ebx0xc(ecx)lock addl $0x0(esp)add $0x8esppop ebptest eax0xb779c000ret

httpgoswegoedudljmmcookbookhtml

32 copy JavaTechDays 2011 Oracle Corporation

Concurrencyvolatile-счётчик

public class VolatileTest

private int counter = 0 private volatile int volatileCounter = 0

GenerateMicroBenchmark public void testOrdinary() counter++

GenerateMicroBenchmark public void testVolatile() volatileCounter++

33 copy JavaTechDays 2011 Oracle Corporation

Concurrencyбесконфликтный volatile-счётчик

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

500000

1000000

1500000

2000000

2500000

3000000

3500000

Thread-local counter performance

ordinary volatile

Threads

op

ss

ec

34 copy JavaTechDays 2011 Oracle Corporation

Concurrencyконфликтный volatile-счётчик

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

100000

200000

300000

400000

500000

600000

700000

800000

900000

Global counter performance

ordinary volatile

Threads

op

ss

ec

35 copy JavaTechDays 2011 Oracle Corporation

Concurrencyintrinsic synchronization

bull synchronized(object) bull 4 состояния

ndash Initbull Начальное ldquoнеопределённоеrdquo состояние

ndash Biasedbull Захватывается одним ldquoвладеющимrdquo потоком нет конфликтовbull Захват владельцем проверка на threadIDbull Захват не-владельцем переход либо в Biased либо в Thin

ndash Thinbull Захватывается несколькими потоками но конфликтов нетbull Захват CASbull Конфликтный захват переход в Fat

ndash Fatbull Захватывается несколькими потоками конфликт на блокировкеbull Вызов примитива синхронизации из ОС

36 copy JavaTechDays 2011 Oracle Corporation

ConcurrencyjavautilconcurrentLock

bull Построены на базе jucAbstractQueueSynchronizerndash Использует атомики

bull CAS

ndash Использует Unsafepark()unpark()

bull интринзики для cond_wait()cond_signal()WaitForSingleObject()

bull ReentrantLockndash По семантике эквивалентен synchronized

bull Рекурсивный захват проверка на threadID

bull Ставит потоки во внутреннюю очередь и делает park()

ndash Non-Fair (default)

bull Не гарантирует отсутствие starvation

bull Barging FIFO (CAS)

bull Лучшая производительность

ndash Fair

bull Гарантирует отсутствие starvation

bull FIFO

bull Честность в обмен на производительностьhttpgeecsoswegoedudlpapersaqspdf

37 copy JavaTechDays 2011 Oracle Corporation

Concurrencyатомарный счётчик

private AtomicInteger atomic = new AtomicInteger() private ReentrantLock lock = new ReentrantLock() private final Object intrinsicLock = new Object() private int primCounter = 0

GenerateMicroBenchmark public void testAtomicInteger() atomicincrementAndGet()

GenerateMicroBenchmark public void testReentrantLock() locklock() primCounter++ lockunlock()

GenerateMicroBenchmark public void testIntrinsicLock() synchronized (intrinsicLock) primCounter++

38 copy JavaTechDays 2011 Oracle Corporation

Concurrencyатомарный счётчик

0 16 32 48 64 80 96 112 128

1000

10000

100000

Atomic Counter Performance

Intrinsic AtomicInteger ReentrantLock

Threads

ops

sec

8x8 CPUs Solaris 6u25

39 copy JavaTechDays 2011 Oracle Corporation

ConcurrencyReentrantLock vs synchronized

bull Семантика одинаковаndash Требования к видимости памяти

ndash Рекурсивный

bull Плюсы jucRLndash Очередь потоков держится на стороне JVM

bull опционально FIFO-политика при захвате-освобождении

bull позволяет быть ldquoчестнымrdquo на любой платформе

ndash Barging FIFO policy

bull lock() может быть сразу удовлетворён даже если в очереди есть потоки

bull сильно улучшает производительность при конфликте блокировок

ndash Допускается несколько Condition

bull Минусы jucRLndash Нет scopeов требуется ручной unlock() через finally

bull Должно быть проще с ARM в JDK7

40 copy JavaTechDays 2011 Oracle Corporation

Concurrencyбесконфликтный захват

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

10000

20000

30000

40000

50000

60000

70000

80000

90000

100000

110000

120000

130000

140000

150000

Uncontended Lock Performance

intrinsic jucReentrantL (non-fair) jucReentrantL (fair)

Threads

op

sse

c

41 copy JavaTechDays 2011 Oracle Corporation

Concurrencyконфликтный захват

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

500

1000

1500

2000

2500

3000

3500

4000

4500

Contended Lock Performance

intrinsic jucReentrantL (non-fair) jucReentrantL (fair)

Threads

op

sse

c

43 copy 2011 JavaTechDays Oracle Corporation

bull hellip естьbull hellip работаетbull hellip работает хорошоbull hellip знает о железе всё

ndash Количество и тип CPUndash Поддерживаемые инcтрукции (SSEx AVX VIS)ndash Топологию памяти (в тч размеры кэшей и их характеристики)

bull hellip знает о приложении много всегоndash Иерархию загруженных классовndash Актуальную статистику создания объектовndash Горячий кодndash Какие ветвления исполнялисьndash Какие значения использовалисьndash Многое другое

bull hellip не боится использовать эти знания для компиляции

JITфакты

44 copy 2011 JavaTechDays Oracle Corporation

JITоптимизации

46 copy 2011 JavaTechDays Oracle Corporation

JITкак писать код

bull Используйте стандартные библиотекиndash Зачем писать собственный стандартный контейнер

bull Используйте высокоуровневый API ndash javautilndash javautilconcurrentndash NIO NIO2ndash вообще библиотеки

bull Код должен правильным и понятнымndash Сначала правильноndash Потом алгоритмически ldquoбыстроrdquondash Код не должен быть JIT-oriented

bull Правильно используйте возможности языкаndash EPIC FAIL штатная передача управления exceptionамиndash FAIL Возврат ldquoисключенияrdquo через return ltкод_ошибкиgtndash FAIL int вместо Enum или boolean

47 copy 2011 JavaTechDays Oracle Corporation

Как получить ассемблерный код метода

ndash Обычным дебаггером )

ndash JVMTI

ndash -XX+PrintAssemblybull httpwikissuncomdisplayHotSpotInternalsPrintAssembly

JITдля любопытных

54 copy JavaTechDays 2011 Oracle Corporation

StartupEclipse

bull Типичная конфигурацияndash 2x2 Intel i5 26 Ghz Ubuntu 1010 i686 JDK 6u25ndash Eclipse JDT (Galileo)

bull Типичные метрикиndash 6000 загруженных классовndash 1000 методов скомпилированоndash 512 Mb зарезервированного пространства в кучеndash 25 Mb кучи использовано после стартапа

bull Известные ldquoпроблемыrdquondash Загрузка и верификация классовndash JIT-компиляция

55 copy JavaTechDays 2011 Oracle Corporation

StartupEclipse

bull Метрика секунд на запуск-завершениеndash Файловые кеши прогреты практически нулевой дисковый IO

default CDS CDS + no-verify

абсолютное время

583 [574 592]

481[473 484]

461[456 474]

загрузка классов

501[491 511]

339[312 366]

301[294 308]

компиляция 051[043 059]

051[044 058]

051[042 060]

56 copy JavaTechDays 2011 Oracle Corporation

Startupдлинные приложения

bull Важно только для коротких приложенийndash Чем дольше работает приложение тем меньше удельные затраты на

загрузку классов и компиляцию

bull Пример 8 часа работает IntelliJ IDEA 10xndash 26600 классов загруженоndash 5315 методов скомпилировано

bull Загрузка классовndash Всего потрачено 202 с ~07 общего времениndash 10 мсек на класс

bull Компиляцияndash Всего потрачено 112 с ~003 общего времениndash 20 мсек на метод

57 copy JavaTechDays 2011 Oracle Corporation

Whats Next

bull Послушать ещёndash JavaOne Moscow (апрель 2011)

bull Проблема со слайдамиndash Найдите нас на конференцииndash Напишите нам письмо

bull Проблема с JDKndash httpopenjdkjavanetndash Задайте вопрос в OpenJDKndash а лучше сделайте патч и дайте его в OpenJDK на review

58 copy JavaTechDays 2011 Oracle Corporation

QA

Page 17: Java Platform Performance BoF - Aleksey Shipilëv · – 2x2 Intel i5 2.6 Ghz, Ubuntu 10.10 i686, JDK 6u25 • Три варианта эксперимента: – 1 экземпляр

22 copy JavaTechDays 2011 Oracle Corporation

Benchmarkingа вот и данные

1 экземпляр 4 экземпляра 16 потоков

ldquoGMPrdquo

884[869 899]

1328 [1286 1371]

1328 [1286 1371]

ldquoBigIntegerrdquo

621 [619 624]

1346 [1335 1356]

1434 [1421 1446]

bull Метрика операции в секундуndash 20 итерацийndash [a b] ndash доверительный интервал на 95

24 copy JavaTechDays 2011 Oracle Corporation

Java 7 Java 8что ожидать в области производительности

bull Java 7ndash invokedynamicndash NIO2ndash Concurrency and Collection updates (ForkJoin)ndash XRender pipeline for Java2D (client)

bull Java 8 (или позже)ndash Модульностьndash -выражения (замыкания)ndash Collection updates (filter map reduce)

25 copy JavaTechDays 2011 Oracle Corporation

bull Мешает ли улучшать производительность JVMndash Да поэтому иногда расширяемся

bull invokedynamicbull Модульность

bull Стоит ли расширяться по первому требованию ndash Нет развитие JVMJIT реализация новых методов оптимизации

позволяет получить бОльший выигрышbull Вложенные классыbull Reflection

Обратная совместимость

26 copy JavaTechDays 2011 Oracle Corporation

Solaris

Лучшая ОС для Javaугадайте какая

bull Высокопроизводительный TCPIP стекndash low-latencyndash up to 50 faster

bull DTracendash мониторинг

bull NUMAndash MPO Memory Placement Optimization

bull Large Pagesndash Автоматическая аллокацияndash Разные размеры

27 copy JavaTechDays 2011 Oracle Corporation

hellip and beyondнастройка параметров JVM

bull Что настраиватьndash httpblogssuncomwattresourcejvm-options-listhtml

ndash httpwwworaclecomtechnetworkjavajavasetechvmoptions-jsp-140102html

bull JVM сама подбирает оптимальные параметры своей работыndash Server vs Client ndash Large pages (Solaris)ndash CompressedOops (64-bit VM)

bull Так что же настраиватьndash GCHeap tuningndash -XX+UseNUMA (Solaris Linux)ndash -XX+UseLargePages (Linux Windows)

bull httpwwworaclecomtechnetworkjavajavasetechlargememory-jsp-137182html

bull Не забытьndash Использовать последнюю версию JDK

29 copy JavaTechDays 2011 Oracle Corporation

Concurrencyэлементная база

bull OS Threadingndash мьютексы

bull mutex_lock()mutex_unlock()ndash conditional waits

bull cond_wait()cond_signal()bull WaitForSingleObject

bull Compare-and-Swap (CAS)ndash CAS(x1 x2 x3) = if (x1 == x2) x1 = x3 ndash атомарная операция поддерживаемая в ldquoжелезеrdquo из нескольких

одновременных CASов успешно завершается только одинndash Миф локальный CAS блокирует шину и стоит больше на

многопроцессорных системах ndash Факт глобальный CAS требует трафика на шине

httpblogssuncomdaveentrybiased_locking_in_hotspot

30 copy JavaTechDays 2011 Oracle Corporation

Concurrencyatomics

bull javautilconcurrentAtomicndash обеспечивают атомарные операции над примитивами и указателямиndash альтернатива synchronized или Lockи

bull Трюк в использовании CASаndash Изменение состояния атомика делается при помощи одного CASаndash Чтение состояния не требует CASа

public final int incrementAndGet() for () int current = get() int next = current + 1 if (compareAndSet(current next)) return next

mov ecxedxmov 0x8(ecx)eaxlea 0x8(ecx)edimov eaxecxinc ecxlock cmpxchg ecx(edi)mov $0x0ebxjne [ok]mov $0x1ebxtest ebxebxje [ok]

31 copy JavaTechDays 2011 Oracle Corporation

Concurrencyvolatile

bull Volatile определяет порядок чтения-записей в полеndash Точная семантика определена в Java Memory Model

bull НЕ обеспечивает атомарностиndash Реализуется расстановкой барьеров

bull Какие из них вставятся в код зависит от Hardware Memory Modelbull Эффект барьера зависит от HMM

PUSHL EBPSUB ESP8MOV EBX[ECX + 12]MEMBAR-acquireMEMBAR-releaseINC EBXMOV [ECX + 12]EBXMEMBAR-volatileLOCK ADDL [ESP + 0] 0ADD ESP8POPL EBPTEST PollPageEAXRET

push ebpsub $0x8espmov 0xc(ecx)ebxinc ebxmov ebx0xc(ecx)lock addl $0x0(esp)add $0x8esppop ebptest eax0xb779c000ret

httpgoswegoedudljmmcookbookhtml

32 copy JavaTechDays 2011 Oracle Corporation

Concurrencyvolatile-счётчик

public class VolatileTest

private int counter = 0 private volatile int volatileCounter = 0

GenerateMicroBenchmark public void testOrdinary() counter++

GenerateMicroBenchmark public void testVolatile() volatileCounter++

33 copy JavaTechDays 2011 Oracle Corporation

Concurrencyбесконфликтный volatile-счётчик

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

500000

1000000

1500000

2000000

2500000

3000000

3500000

Thread-local counter performance

ordinary volatile

Threads

op

ss

ec

34 copy JavaTechDays 2011 Oracle Corporation

Concurrencyконфликтный volatile-счётчик

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

100000

200000

300000

400000

500000

600000

700000

800000

900000

Global counter performance

ordinary volatile

Threads

op

ss

ec

35 copy JavaTechDays 2011 Oracle Corporation

Concurrencyintrinsic synchronization

bull synchronized(object) bull 4 состояния

ndash Initbull Начальное ldquoнеопределённоеrdquo состояние

ndash Biasedbull Захватывается одним ldquoвладеющимrdquo потоком нет конфликтовbull Захват владельцем проверка на threadIDbull Захват не-владельцем переход либо в Biased либо в Thin

ndash Thinbull Захватывается несколькими потоками но конфликтов нетbull Захват CASbull Конфликтный захват переход в Fat

ndash Fatbull Захватывается несколькими потоками конфликт на блокировкеbull Вызов примитива синхронизации из ОС

36 copy JavaTechDays 2011 Oracle Corporation

ConcurrencyjavautilconcurrentLock

bull Построены на базе jucAbstractQueueSynchronizerndash Использует атомики

bull CAS

ndash Использует Unsafepark()unpark()

bull интринзики для cond_wait()cond_signal()WaitForSingleObject()

bull ReentrantLockndash По семантике эквивалентен synchronized

bull Рекурсивный захват проверка на threadID

bull Ставит потоки во внутреннюю очередь и делает park()

ndash Non-Fair (default)

bull Не гарантирует отсутствие starvation

bull Barging FIFO (CAS)

bull Лучшая производительность

ndash Fair

bull Гарантирует отсутствие starvation

bull FIFO

bull Честность в обмен на производительностьhttpgeecsoswegoedudlpapersaqspdf

37 copy JavaTechDays 2011 Oracle Corporation

Concurrencyатомарный счётчик

private AtomicInteger atomic = new AtomicInteger() private ReentrantLock lock = new ReentrantLock() private final Object intrinsicLock = new Object() private int primCounter = 0

GenerateMicroBenchmark public void testAtomicInteger() atomicincrementAndGet()

GenerateMicroBenchmark public void testReentrantLock() locklock() primCounter++ lockunlock()

GenerateMicroBenchmark public void testIntrinsicLock() synchronized (intrinsicLock) primCounter++

38 copy JavaTechDays 2011 Oracle Corporation

Concurrencyатомарный счётчик

0 16 32 48 64 80 96 112 128

1000

10000

100000

Atomic Counter Performance

Intrinsic AtomicInteger ReentrantLock

Threads

ops

sec

8x8 CPUs Solaris 6u25

39 copy JavaTechDays 2011 Oracle Corporation

ConcurrencyReentrantLock vs synchronized

bull Семантика одинаковаndash Требования к видимости памяти

ndash Рекурсивный

bull Плюсы jucRLndash Очередь потоков держится на стороне JVM

bull опционально FIFO-политика при захвате-освобождении

bull позволяет быть ldquoчестнымrdquo на любой платформе

ndash Barging FIFO policy

bull lock() может быть сразу удовлетворён даже если в очереди есть потоки

bull сильно улучшает производительность при конфликте блокировок

ndash Допускается несколько Condition

bull Минусы jucRLndash Нет scopeов требуется ручной unlock() через finally

bull Должно быть проще с ARM в JDK7

40 copy JavaTechDays 2011 Oracle Corporation

Concurrencyбесконфликтный захват

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

10000

20000

30000

40000

50000

60000

70000

80000

90000

100000

110000

120000

130000

140000

150000

Uncontended Lock Performance

intrinsic jucReentrantL (non-fair) jucReentrantL (fair)

Threads

op

sse

c

41 copy JavaTechDays 2011 Oracle Corporation

Concurrencyконфликтный захват

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

500

1000

1500

2000

2500

3000

3500

4000

4500

Contended Lock Performance

intrinsic jucReentrantL (non-fair) jucReentrantL (fair)

Threads

op

sse

c

43 copy 2011 JavaTechDays Oracle Corporation

bull hellip естьbull hellip работаетbull hellip работает хорошоbull hellip знает о железе всё

ndash Количество и тип CPUndash Поддерживаемые инcтрукции (SSEx AVX VIS)ndash Топологию памяти (в тч размеры кэшей и их характеристики)

bull hellip знает о приложении много всегоndash Иерархию загруженных классовndash Актуальную статистику создания объектовndash Горячий кодndash Какие ветвления исполнялисьndash Какие значения использовалисьndash Многое другое

bull hellip не боится использовать эти знания для компиляции

JITфакты

44 copy 2011 JavaTechDays Oracle Corporation

JITоптимизации

46 copy 2011 JavaTechDays Oracle Corporation

JITкак писать код

bull Используйте стандартные библиотекиndash Зачем писать собственный стандартный контейнер

bull Используйте высокоуровневый API ndash javautilndash javautilconcurrentndash NIO NIO2ndash вообще библиотеки

bull Код должен правильным и понятнымndash Сначала правильноndash Потом алгоритмически ldquoбыстроrdquondash Код не должен быть JIT-oriented

bull Правильно используйте возможности языкаndash EPIC FAIL штатная передача управления exceptionамиndash FAIL Возврат ldquoисключенияrdquo через return ltкод_ошибкиgtndash FAIL int вместо Enum или boolean

47 copy 2011 JavaTechDays Oracle Corporation

Как получить ассемблерный код метода

ndash Обычным дебаггером )

ndash JVMTI

ndash -XX+PrintAssemblybull httpwikissuncomdisplayHotSpotInternalsPrintAssembly

JITдля любопытных

54 copy JavaTechDays 2011 Oracle Corporation

StartupEclipse

bull Типичная конфигурацияndash 2x2 Intel i5 26 Ghz Ubuntu 1010 i686 JDK 6u25ndash Eclipse JDT (Galileo)

bull Типичные метрикиndash 6000 загруженных классовndash 1000 методов скомпилированоndash 512 Mb зарезервированного пространства в кучеndash 25 Mb кучи использовано после стартапа

bull Известные ldquoпроблемыrdquondash Загрузка и верификация классовndash JIT-компиляция

55 copy JavaTechDays 2011 Oracle Corporation

StartupEclipse

bull Метрика секунд на запуск-завершениеndash Файловые кеши прогреты практически нулевой дисковый IO

default CDS CDS + no-verify

абсолютное время

583 [574 592]

481[473 484]

461[456 474]

загрузка классов

501[491 511]

339[312 366]

301[294 308]

компиляция 051[043 059]

051[044 058]

051[042 060]

56 copy JavaTechDays 2011 Oracle Corporation

Startupдлинные приложения

bull Важно только для коротких приложенийndash Чем дольше работает приложение тем меньше удельные затраты на

загрузку классов и компиляцию

bull Пример 8 часа работает IntelliJ IDEA 10xndash 26600 классов загруженоndash 5315 методов скомпилировано

bull Загрузка классовndash Всего потрачено 202 с ~07 общего времениndash 10 мсек на класс

bull Компиляцияndash Всего потрачено 112 с ~003 общего времениndash 20 мсек на метод

57 copy JavaTechDays 2011 Oracle Corporation

Whats Next

bull Послушать ещёndash JavaOne Moscow (апрель 2011)

bull Проблема со слайдамиndash Найдите нас на конференцииndash Напишите нам письмо

bull Проблема с JDKndash httpopenjdkjavanetndash Задайте вопрос в OpenJDKndash а лучше сделайте патч и дайте его в OpenJDK на review

58 copy JavaTechDays 2011 Oracle Corporation

QA

Page 18: Java Platform Performance BoF - Aleksey Shipilëv · – 2x2 Intel i5 2.6 Ghz, Ubuntu 10.10 i686, JDK 6u25 • Три варианта эксперимента: – 1 экземпляр

24 copy JavaTechDays 2011 Oracle Corporation

Java 7 Java 8что ожидать в области производительности

bull Java 7ndash invokedynamicndash NIO2ndash Concurrency and Collection updates (ForkJoin)ndash XRender pipeline for Java2D (client)

bull Java 8 (или позже)ndash Модульностьndash -выражения (замыкания)ndash Collection updates (filter map reduce)

25 copy JavaTechDays 2011 Oracle Corporation

bull Мешает ли улучшать производительность JVMndash Да поэтому иногда расширяемся

bull invokedynamicbull Модульность

bull Стоит ли расширяться по первому требованию ndash Нет развитие JVMJIT реализация новых методов оптимизации

позволяет получить бОльший выигрышbull Вложенные классыbull Reflection

Обратная совместимость

26 copy JavaTechDays 2011 Oracle Corporation

Solaris

Лучшая ОС для Javaугадайте какая

bull Высокопроизводительный TCPIP стекndash low-latencyndash up to 50 faster

bull DTracendash мониторинг

bull NUMAndash MPO Memory Placement Optimization

bull Large Pagesndash Автоматическая аллокацияndash Разные размеры

27 copy JavaTechDays 2011 Oracle Corporation

hellip and beyondнастройка параметров JVM

bull Что настраиватьndash httpblogssuncomwattresourcejvm-options-listhtml

ndash httpwwworaclecomtechnetworkjavajavasetechvmoptions-jsp-140102html

bull JVM сама подбирает оптимальные параметры своей работыndash Server vs Client ndash Large pages (Solaris)ndash CompressedOops (64-bit VM)

bull Так что же настраиватьndash GCHeap tuningndash -XX+UseNUMA (Solaris Linux)ndash -XX+UseLargePages (Linux Windows)

bull httpwwworaclecomtechnetworkjavajavasetechlargememory-jsp-137182html

bull Не забытьndash Использовать последнюю версию JDK

29 copy JavaTechDays 2011 Oracle Corporation

Concurrencyэлементная база

bull OS Threadingndash мьютексы

bull mutex_lock()mutex_unlock()ndash conditional waits

bull cond_wait()cond_signal()bull WaitForSingleObject

bull Compare-and-Swap (CAS)ndash CAS(x1 x2 x3) = if (x1 == x2) x1 = x3 ndash атомарная операция поддерживаемая в ldquoжелезеrdquo из нескольких

одновременных CASов успешно завершается только одинndash Миф локальный CAS блокирует шину и стоит больше на

многопроцессорных системах ndash Факт глобальный CAS требует трафика на шине

httpblogssuncomdaveentrybiased_locking_in_hotspot

30 copy JavaTechDays 2011 Oracle Corporation

Concurrencyatomics

bull javautilconcurrentAtomicndash обеспечивают атомарные операции над примитивами и указателямиndash альтернатива synchronized или Lockи

bull Трюк в использовании CASаndash Изменение состояния атомика делается при помощи одного CASаndash Чтение состояния не требует CASа

public final int incrementAndGet() for () int current = get() int next = current + 1 if (compareAndSet(current next)) return next

mov ecxedxmov 0x8(ecx)eaxlea 0x8(ecx)edimov eaxecxinc ecxlock cmpxchg ecx(edi)mov $0x0ebxjne [ok]mov $0x1ebxtest ebxebxje [ok]

31 copy JavaTechDays 2011 Oracle Corporation

Concurrencyvolatile

bull Volatile определяет порядок чтения-записей в полеndash Точная семантика определена в Java Memory Model

bull НЕ обеспечивает атомарностиndash Реализуется расстановкой барьеров

bull Какие из них вставятся в код зависит от Hardware Memory Modelbull Эффект барьера зависит от HMM

PUSHL EBPSUB ESP8MOV EBX[ECX + 12]MEMBAR-acquireMEMBAR-releaseINC EBXMOV [ECX + 12]EBXMEMBAR-volatileLOCK ADDL [ESP + 0] 0ADD ESP8POPL EBPTEST PollPageEAXRET

push ebpsub $0x8espmov 0xc(ecx)ebxinc ebxmov ebx0xc(ecx)lock addl $0x0(esp)add $0x8esppop ebptest eax0xb779c000ret

httpgoswegoedudljmmcookbookhtml

32 copy JavaTechDays 2011 Oracle Corporation

Concurrencyvolatile-счётчик

public class VolatileTest

private int counter = 0 private volatile int volatileCounter = 0

GenerateMicroBenchmark public void testOrdinary() counter++

GenerateMicroBenchmark public void testVolatile() volatileCounter++

33 copy JavaTechDays 2011 Oracle Corporation

Concurrencyбесконфликтный volatile-счётчик

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

500000

1000000

1500000

2000000

2500000

3000000

3500000

Thread-local counter performance

ordinary volatile

Threads

op

ss

ec

34 copy JavaTechDays 2011 Oracle Corporation

Concurrencyконфликтный volatile-счётчик

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

100000

200000

300000

400000

500000

600000

700000

800000

900000

Global counter performance

ordinary volatile

Threads

op

ss

ec

35 copy JavaTechDays 2011 Oracle Corporation

Concurrencyintrinsic synchronization

bull synchronized(object) bull 4 состояния

ndash Initbull Начальное ldquoнеопределённоеrdquo состояние

ndash Biasedbull Захватывается одним ldquoвладеющимrdquo потоком нет конфликтовbull Захват владельцем проверка на threadIDbull Захват не-владельцем переход либо в Biased либо в Thin

ndash Thinbull Захватывается несколькими потоками но конфликтов нетbull Захват CASbull Конфликтный захват переход в Fat

ndash Fatbull Захватывается несколькими потоками конфликт на блокировкеbull Вызов примитива синхронизации из ОС

36 copy JavaTechDays 2011 Oracle Corporation

ConcurrencyjavautilconcurrentLock

bull Построены на базе jucAbstractQueueSynchronizerndash Использует атомики

bull CAS

ndash Использует Unsafepark()unpark()

bull интринзики для cond_wait()cond_signal()WaitForSingleObject()

bull ReentrantLockndash По семантике эквивалентен synchronized

bull Рекурсивный захват проверка на threadID

bull Ставит потоки во внутреннюю очередь и делает park()

ndash Non-Fair (default)

bull Не гарантирует отсутствие starvation

bull Barging FIFO (CAS)

bull Лучшая производительность

ndash Fair

bull Гарантирует отсутствие starvation

bull FIFO

bull Честность в обмен на производительностьhttpgeecsoswegoedudlpapersaqspdf

37 copy JavaTechDays 2011 Oracle Corporation

Concurrencyатомарный счётчик

private AtomicInteger atomic = new AtomicInteger() private ReentrantLock lock = new ReentrantLock() private final Object intrinsicLock = new Object() private int primCounter = 0

GenerateMicroBenchmark public void testAtomicInteger() atomicincrementAndGet()

GenerateMicroBenchmark public void testReentrantLock() locklock() primCounter++ lockunlock()

GenerateMicroBenchmark public void testIntrinsicLock() synchronized (intrinsicLock) primCounter++

38 copy JavaTechDays 2011 Oracle Corporation

Concurrencyатомарный счётчик

0 16 32 48 64 80 96 112 128

1000

10000

100000

Atomic Counter Performance

Intrinsic AtomicInteger ReentrantLock

Threads

ops

sec

8x8 CPUs Solaris 6u25

39 copy JavaTechDays 2011 Oracle Corporation

ConcurrencyReentrantLock vs synchronized

bull Семантика одинаковаndash Требования к видимости памяти

ndash Рекурсивный

bull Плюсы jucRLndash Очередь потоков держится на стороне JVM

bull опционально FIFO-политика при захвате-освобождении

bull позволяет быть ldquoчестнымrdquo на любой платформе

ndash Barging FIFO policy

bull lock() может быть сразу удовлетворён даже если в очереди есть потоки

bull сильно улучшает производительность при конфликте блокировок

ndash Допускается несколько Condition

bull Минусы jucRLndash Нет scopeов требуется ручной unlock() через finally

bull Должно быть проще с ARM в JDK7

40 copy JavaTechDays 2011 Oracle Corporation

Concurrencyбесконфликтный захват

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

10000

20000

30000

40000

50000

60000

70000

80000

90000

100000

110000

120000

130000

140000

150000

Uncontended Lock Performance

intrinsic jucReentrantL (non-fair) jucReentrantL (fair)

Threads

op

sse

c

41 copy JavaTechDays 2011 Oracle Corporation

Concurrencyконфликтный захват

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

500

1000

1500

2000

2500

3000

3500

4000

4500

Contended Lock Performance

intrinsic jucReentrantL (non-fair) jucReentrantL (fair)

Threads

op

sse

c

43 copy 2011 JavaTechDays Oracle Corporation

bull hellip естьbull hellip работаетbull hellip работает хорошоbull hellip знает о железе всё

ndash Количество и тип CPUndash Поддерживаемые инcтрукции (SSEx AVX VIS)ndash Топологию памяти (в тч размеры кэшей и их характеристики)

bull hellip знает о приложении много всегоndash Иерархию загруженных классовndash Актуальную статистику создания объектовndash Горячий кодndash Какие ветвления исполнялисьndash Какие значения использовалисьndash Многое другое

bull hellip не боится использовать эти знания для компиляции

JITфакты

44 copy 2011 JavaTechDays Oracle Corporation

JITоптимизации

46 copy 2011 JavaTechDays Oracle Corporation

JITкак писать код

bull Используйте стандартные библиотекиndash Зачем писать собственный стандартный контейнер

bull Используйте высокоуровневый API ndash javautilndash javautilconcurrentndash NIO NIO2ndash вообще библиотеки

bull Код должен правильным и понятнымndash Сначала правильноndash Потом алгоритмически ldquoбыстроrdquondash Код не должен быть JIT-oriented

bull Правильно используйте возможности языкаndash EPIC FAIL штатная передача управления exceptionамиndash FAIL Возврат ldquoисключенияrdquo через return ltкод_ошибкиgtndash FAIL int вместо Enum или boolean

47 copy 2011 JavaTechDays Oracle Corporation

Как получить ассемблерный код метода

ndash Обычным дебаггером )

ndash JVMTI

ndash -XX+PrintAssemblybull httpwikissuncomdisplayHotSpotInternalsPrintAssembly

JITдля любопытных

54 copy JavaTechDays 2011 Oracle Corporation

StartupEclipse

bull Типичная конфигурацияndash 2x2 Intel i5 26 Ghz Ubuntu 1010 i686 JDK 6u25ndash Eclipse JDT (Galileo)

bull Типичные метрикиndash 6000 загруженных классовndash 1000 методов скомпилированоndash 512 Mb зарезервированного пространства в кучеndash 25 Mb кучи использовано после стартапа

bull Известные ldquoпроблемыrdquondash Загрузка и верификация классовndash JIT-компиляция

55 copy JavaTechDays 2011 Oracle Corporation

StartupEclipse

bull Метрика секунд на запуск-завершениеndash Файловые кеши прогреты практически нулевой дисковый IO

default CDS CDS + no-verify

абсолютное время

583 [574 592]

481[473 484]

461[456 474]

загрузка классов

501[491 511]

339[312 366]

301[294 308]

компиляция 051[043 059]

051[044 058]

051[042 060]

56 copy JavaTechDays 2011 Oracle Corporation

Startupдлинные приложения

bull Важно только для коротких приложенийndash Чем дольше работает приложение тем меньше удельные затраты на

загрузку классов и компиляцию

bull Пример 8 часа работает IntelliJ IDEA 10xndash 26600 классов загруженоndash 5315 методов скомпилировано

bull Загрузка классовndash Всего потрачено 202 с ~07 общего времениndash 10 мсек на класс

bull Компиляцияndash Всего потрачено 112 с ~003 общего времениndash 20 мсек на метод

57 copy JavaTechDays 2011 Oracle Corporation

Whats Next

bull Послушать ещёndash JavaOne Moscow (апрель 2011)

bull Проблема со слайдамиndash Найдите нас на конференцииndash Напишите нам письмо

bull Проблема с JDKndash httpopenjdkjavanetndash Задайте вопрос в OpenJDKndash а лучше сделайте патч и дайте его в OpenJDK на review

58 copy JavaTechDays 2011 Oracle Corporation

QA

Page 19: Java Platform Performance BoF - Aleksey Shipilëv · – 2x2 Intel i5 2.6 Ghz, Ubuntu 10.10 i686, JDK 6u25 • Три варианта эксперимента: – 1 экземпляр

25 copy JavaTechDays 2011 Oracle Corporation

bull Мешает ли улучшать производительность JVMndash Да поэтому иногда расширяемся

bull invokedynamicbull Модульность

bull Стоит ли расширяться по первому требованию ndash Нет развитие JVMJIT реализация новых методов оптимизации

позволяет получить бОльший выигрышbull Вложенные классыbull Reflection

Обратная совместимость

26 copy JavaTechDays 2011 Oracle Corporation

Solaris

Лучшая ОС для Javaугадайте какая

bull Высокопроизводительный TCPIP стекndash low-latencyndash up to 50 faster

bull DTracendash мониторинг

bull NUMAndash MPO Memory Placement Optimization

bull Large Pagesndash Автоматическая аллокацияndash Разные размеры

27 copy JavaTechDays 2011 Oracle Corporation

hellip and beyondнастройка параметров JVM

bull Что настраиватьndash httpblogssuncomwattresourcejvm-options-listhtml

ndash httpwwworaclecomtechnetworkjavajavasetechvmoptions-jsp-140102html

bull JVM сама подбирает оптимальные параметры своей работыndash Server vs Client ndash Large pages (Solaris)ndash CompressedOops (64-bit VM)

bull Так что же настраиватьndash GCHeap tuningndash -XX+UseNUMA (Solaris Linux)ndash -XX+UseLargePages (Linux Windows)

bull httpwwworaclecomtechnetworkjavajavasetechlargememory-jsp-137182html

bull Не забытьndash Использовать последнюю версию JDK

29 copy JavaTechDays 2011 Oracle Corporation

Concurrencyэлементная база

bull OS Threadingndash мьютексы

bull mutex_lock()mutex_unlock()ndash conditional waits

bull cond_wait()cond_signal()bull WaitForSingleObject

bull Compare-and-Swap (CAS)ndash CAS(x1 x2 x3) = if (x1 == x2) x1 = x3 ndash атомарная операция поддерживаемая в ldquoжелезеrdquo из нескольких

одновременных CASов успешно завершается только одинndash Миф локальный CAS блокирует шину и стоит больше на

многопроцессорных системах ndash Факт глобальный CAS требует трафика на шине

httpblogssuncomdaveentrybiased_locking_in_hotspot

30 copy JavaTechDays 2011 Oracle Corporation

Concurrencyatomics

bull javautilconcurrentAtomicndash обеспечивают атомарные операции над примитивами и указателямиndash альтернатива synchronized или Lockи

bull Трюк в использовании CASаndash Изменение состояния атомика делается при помощи одного CASаndash Чтение состояния не требует CASа

public final int incrementAndGet() for () int current = get() int next = current + 1 if (compareAndSet(current next)) return next

mov ecxedxmov 0x8(ecx)eaxlea 0x8(ecx)edimov eaxecxinc ecxlock cmpxchg ecx(edi)mov $0x0ebxjne [ok]mov $0x1ebxtest ebxebxje [ok]

31 copy JavaTechDays 2011 Oracle Corporation

Concurrencyvolatile

bull Volatile определяет порядок чтения-записей в полеndash Точная семантика определена в Java Memory Model

bull НЕ обеспечивает атомарностиndash Реализуется расстановкой барьеров

bull Какие из них вставятся в код зависит от Hardware Memory Modelbull Эффект барьера зависит от HMM

PUSHL EBPSUB ESP8MOV EBX[ECX + 12]MEMBAR-acquireMEMBAR-releaseINC EBXMOV [ECX + 12]EBXMEMBAR-volatileLOCK ADDL [ESP + 0] 0ADD ESP8POPL EBPTEST PollPageEAXRET

push ebpsub $0x8espmov 0xc(ecx)ebxinc ebxmov ebx0xc(ecx)lock addl $0x0(esp)add $0x8esppop ebptest eax0xb779c000ret

httpgoswegoedudljmmcookbookhtml

32 copy JavaTechDays 2011 Oracle Corporation

Concurrencyvolatile-счётчик

public class VolatileTest

private int counter = 0 private volatile int volatileCounter = 0

GenerateMicroBenchmark public void testOrdinary() counter++

GenerateMicroBenchmark public void testVolatile() volatileCounter++

33 copy JavaTechDays 2011 Oracle Corporation

Concurrencyбесконфликтный volatile-счётчик

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

500000

1000000

1500000

2000000

2500000

3000000

3500000

Thread-local counter performance

ordinary volatile

Threads

op

ss

ec

34 copy JavaTechDays 2011 Oracle Corporation

Concurrencyконфликтный volatile-счётчик

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

100000

200000

300000

400000

500000

600000

700000

800000

900000

Global counter performance

ordinary volatile

Threads

op

ss

ec

35 copy JavaTechDays 2011 Oracle Corporation

Concurrencyintrinsic synchronization

bull synchronized(object) bull 4 состояния

ndash Initbull Начальное ldquoнеопределённоеrdquo состояние

ndash Biasedbull Захватывается одним ldquoвладеющимrdquo потоком нет конфликтовbull Захват владельцем проверка на threadIDbull Захват не-владельцем переход либо в Biased либо в Thin

ndash Thinbull Захватывается несколькими потоками но конфликтов нетbull Захват CASbull Конфликтный захват переход в Fat

ndash Fatbull Захватывается несколькими потоками конфликт на блокировкеbull Вызов примитива синхронизации из ОС

36 copy JavaTechDays 2011 Oracle Corporation

ConcurrencyjavautilconcurrentLock

bull Построены на базе jucAbstractQueueSynchronizerndash Использует атомики

bull CAS

ndash Использует Unsafepark()unpark()

bull интринзики для cond_wait()cond_signal()WaitForSingleObject()

bull ReentrantLockndash По семантике эквивалентен synchronized

bull Рекурсивный захват проверка на threadID

bull Ставит потоки во внутреннюю очередь и делает park()

ndash Non-Fair (default)

bull Не гарантирует отсутствие starvation

bull Barging FIFO (CAS)

bull Лучшая производительность

ndash Fair

bull Гарантирует отсутствие starvation

bull FIFO

bull Честность в обмен на производительностьhttpgeecsoswegoedudlpapersaqspdf

37 copy JavaTechDays 2011 Oracle Corporation

Concurrencyатомарный счётчик

private AtomicInteger atomic = new AtomicInteger() private ReentrantLock lock = new ReentrantLock() private final Object intrinsicLock = new Object() private int primCounter = 0

GenerateMicroBenchmark public void testAtomicInteger() atomicincrementAndGet()

GenerateMicroBenchmark public void testReentrantLock() locklock() primCounter++ lockunlock()

GenerateMicroBenchmark public void testIntrinsicLock() synchronized (intrinsicLock) primCounter++

38 copy JavaTechDays 2011 Oracle Corporation

Concurrencyатомарный счётчик

0 16 32 48 64 80 96 112 128

1000

10000

100000

Atomic Counter Performance

Intrinsic AtomicInteger ReentrantLock

Threads

ops

sec

8x8 CPUs Solaris 6u25

39 copy JavaTechDays 2011 Oracle Corporation

ConcurrencyReentrantLock vs synchronized

bull Семантика одинаковаndash Требования к видимости памяти

ndash Рекурсивный

bull Плюсы jucRLndash Очередь потоков держится на стороне JVM

bull опционально FIFO-политика при захвате-освобождении

bull позволяет быть ldquoчестнымrdquo на любой платформе

ndash Barging FIFO policy

bull lock() может быть сразу удовлетворён даже если в очереди есть потоки

bull сильно улучшает производительность при конфликте блокировок

ndash Допускается несколько Condition

bull Минусы jucRLndash Нет scopeов требуется ручной unlock() через finally

bull Должно быть проще с ARM в JDK7

40 copy JavaTechDays 2011 Oracle Corporation

Concurrencyбесконфликтный захват

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

10000

20000

30000

40000

50000

60000

70000

80000

90000

100000

110000

120000

130000

140000

150000

Uncontended Lock Performance

intrinsic jucReentrantL (non-fair) jucReentrantL (fair)

Threads

op

sse

c

41 copy JavaTechDays 2011 Oracle Corporation

Concurrencyконфликтный захват

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

500

1000

1500

2000

2500

3000

3500

4000

4500

Contended Lock Performance

intrinsic jucReentrantL (non-fair) jucReentrantL (fair)

Threads

op

sse

c

43 copy 2011 JavaTechDays Oracle Corporation

bull hellip естьbull hellip работаетbull hellip работает хорошоbull hellip знает о железе всё

ndash Количество и тип CPUndash Поддерживаемые инcтрукции (SSEx AVX VIS)ndash Топологию памяти (в тч размеры кэшей и их характеристики)

bull hellip знает о приложении много всегоndash Иерархию загруженных классовndash Актуальную статистику создания объектовndash Горячий кодndash Какие ветвления исполнялисьndash Какие значения использовалисьndash Многое другое

bull hellip не боится использовать эти знания для компиляции

JITфакты

44 copy 2011 JavaTechDays Oracle Corporation

JITоптимизации

46 copy 2011 JavaTechDays Oracle Corporation

JITкак писать код

bull Используйте стандартные библиотекиndash Зачем писать собственный стандартный контейнер

bull Используйте высокоуровневый API ndash javautilndash javautilconcurrentndash NIO NIO2ndash вообще библиотеки

bull Код должен правильным и понятнымndash Сначала правильноndash Потом алгоритмически ldquoбыстроrdquondash Код не должен быть JIT-oriented

bull Правильно используйте возможности языкаndash EPIC FAIL штатная передача управления exceptionамиndash FAIL Возврат ldquoисключенияrdquo через return ltкод_ошибкиgtndash FAIL int вместо Enum или boolean

47 copy 2011 JavaTechDays Oracle Corporation

Как получить ассемблерный код метода

ndash Обычным дебаггером )

ndash JVMTI

ndash -XX+PrintAssemblybull httpwikissuncomdisplayHotSpotInternalsPrintAssembly

JITдля любопытных

54 copy JavaTechDays 2011 Oracle Corporation

StartupEclipse

bull Типичная конфигурацияndash 2x2 Intel i5 26 Ghz Ubuntu 1010 i686 JDK 6u25ndash Eclipse JDT (Galileo)

bull Типичные метрикиndash 6000 загруженных классовndash 1000 методов скомпилированоndash 512 Mb зарезервированного пространства в кучеndash 25 Mb кучи использовано после стартапа

bull Известные ldquoпроблемыrdquondash Загрузка и верификация классовndash JIT-компиляция

55 copy JavaTechDays 2011 Oracle Corporation

StartupEclipse

bull Метрика секунд на запуск-завершениеndash Файловые кеши прогреты практически нулевой дисковый IO

default CDS CDS + no-verify

абсолютное время

583 [574 592]

481[473 484]

461[456 474]

загрузка классов

501[491 511]

339[312 366]

301[294 308]

компиляция 051[043 059]

051[044 058]

051[042 060]

56 copy JavaTechDays 2011 Oracle Corporation

Startupдлинные приложения

bull Важно только для коротких приложенийndash Чем дольше работает приложение тем меньше удельные затраты на

загрузку классов и компиляцию

bull Пример 8 часа работает IntelliJ IDEA 10xndash 26600 классов загруженоndash 5315 методов скомпилировано

bull Загрузка классовndash Всего потрачено 202 с ~07 общего времениndash 10 мсек на класс

bull Компиляцияndash Всего потрачено 112 с ~003 общего времениndash 20 мсек на метод

57 copy JavaTechDays 2011 Oracle Corporation

Whats Next

bull Послушать ещёndash JavaOne Moscow (апрель 2011)

bull Проблема со слайдамиndash Найдите нас на конференцииndash Напишите нам письмо

bull Проблема с JDKndash httpopenjdkjavanetndash Задайте вопрос в OpenJDKndash а лучше сделайте патч и дайте его в OpenJDK на review

58 copy JavaTechDays 2011 Oracle Corporation

QA

Page 20: Java Platform Performance BoF - Aleksey Shipilëv · – 2x2 Intel i5 2.6 Ghz, Ubuntu 10.10 i686, JDK 6u25 • Три варианта эксперимента: – 1 экземпляр

26 copy JavaTechDays 2011 Oracle Corporation

Solaris

Лучшая ОС для Javaугадайте какая

bull Высокопроизводительный TCPIP стекndash low-latencyndash up to 50 faster

bull DTracendash мониторинг

bull NUMAndash MPO Memory Placement Optimization

bull Large Pagesndash Автоматическая аллокацияndash Разные размеры

27 copy JavaTechDays 2011 Oracle Corporation

hellip and beyondнастройка параметров JVM

bull Что настраиватьndash httpblogssuncomwattresourcejvm-options-listhtml

ndash httpwwworaclecomtechnetworkjavajavasetechvmoptions-jsp-140102html

bull JVM сама подбирает оптимальные параметры своей работыndash Server vs Client ndash Large pages (Solaris)ndash CompressedOops (64-bit VM)

bull Так что же настраиватьndash GCHeap tuningndash -XX+UseNUMA (Solaris Linux)ndash -XX+UseLargePages (Linux Windows)

bull httpwwworaclecomtechnetworkjavajavasetechlargememory-jsp-137182html

bull Не забытьndash Использовать последнюю версию JDK

29 copy JavaTechDays 2011 Oracle Corporation

Concurrencyэлементная база

bull OS Threadingndash мьютексы

bull mutex_lock()mutex_unlock()ndash conditional waits

bull cond_wait()cond_signal()bull WaitForSingleObject

bull Compare-and-Swap (CAS)ndash CAS(x1 x2 x3) = if (x1 == x2) x1 = x3 ndash атомарная операция поддерживаемая в ldquoжелезеrdquo из нескольких

одновременных CASов успешно завершается только одинndash Миф локальный CAS блокирует шину и стоит больше на

многопроцессорных системах ndash Факт глобальный CAS требует трафика на шине

httpblogssuncomdaveentrybiased_locking_in_hotspot

30 copy JavaTechDays 2011 Oracle Corporation

Concurrencyatomics

bull javautilconcurrentAtomicndash обеспечивают атомарные операции над примитивами и указателямиndash альтернатива synchronized или Lockи

bull Трюк в использовании CASаndash Изменение состояния атомика делается при помощи одного CASаndash Чтение состояния не требует CASа

public final int incrementAndGet() for () int current = get() int next = current + 1 if (compareAndSet(current next)) return next

mov ecxedxmov 0x8(ecx)eaxlea 0x8(ecx)edimov eaxecxinc ecxlock cmpxchg ecx(edi)mov $0x0ebxjne [ok]mov $0x1ebxtest ebxebxje [ok]

31 copy JavaTechDays 2011 Oracle Corporation

Concurrencyvolatile

bull Volatile определяет порядок чтения-записей в полеndash Точная семантика определена в Java Memory Model

bull НЕ обеспечивает атомарностиndash Реализуется расстановкой барьеров

bull Какие из них вставятся в код зависит от Hardware Memory Modelbull Эффект барьера зависит от HMM

PUSHL EBPSUB ESP8MOV EBX[ECX + 12]MEMBAR-acquireMEMBAR-releaseINC EBXMOV [ECX + 12]EBXMEMBAR-volatileLOCK ADDL [ESP + 0] 0ADD ESP8POPL EBPTEST PollPageEAXRET

push ebpsub $0x8espmov 0xc(ecx)ebxinc ebxmov ebx0xc(ecx)lock addl $0x0(esp)add $0x8esppop ebptest eax0xb779c000ret

httpgoswegoedudljmmcookbookhtml

32 copy JavaTechDays 2011 Oracle Corporation

Concurrencyvolatile-счётчик

public class VolatileTest

private int counter = 0 private volatile int volatileCounter = 0

GenerateMicroBenchmark public void testOrdinary() counter++

GenerateMicroBenchmark public void testVolatile() volatileCounter++

33 copy JavaTechDays 2011 Oracle Corporation

Concurrencyбесконфликтный volatile-счётчик

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

500000

1000000

1500000

2000000

2500000

3000000

3500000

Thread-local counter performance

ordinary volatile

Threads

op

ss

ec

34 copy JavaTechDays 2011 Oracle Corporation

Concurrencyконфликтный volatile-счётчик

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

100000

200000

300000

400000

500000

600000

700000

800000

900000

Global counter performance

ordinary volatile

Threads

op

ss

ec

35 copy JavaTechDays 2011 Oracle Corporation

Concurrencyintrinsic synchronization

bull synchronized(object) bull 4 состояния

ndash Initbull Начальное ldquoнеопределённоеrdquo состояние

ndash Biasedbull Захватывается одним ldquoвладеющимrdquo потоком нет конфликтовbull Захват владельцем проверка на threadIDbull Захват не-владельцем переход либо в Biased либо в Thin

ndash Thinbull Захватывается несколькими потоками но конфликтов нетbull Захват CASbull Конфликтный захват переход в Fat

ndash Fatbull Захватывается несколькими потоками конфликт на блокировкеbull Вызов примитива синхронизации из ОС

36 copy JavaTechDays 2011 Oracle Corporation

ConcurrencyjavautilconcurrentLock

bull Построены на базе jucAbstractQueueSynchronizerndash Использует атомики

bull CAS

ndash Использует Unsafepark()unpark()

bull интринзики для cond_wait()cond_signal()WaitForSingleObject()

bull ReentrantLockndash По семантике эквивалентен synchronized

bull Рекурсивный захват проверка на threadID

bull Ставит потоки во внутреннюю очередь и делает park()

ndash Non-Fair (default)

bull Не гарантирует отсутствие starvation

bull Barging FIFO (CAS)

bull Лучшая производительность

ndash Fair

bull Гарантирует отсутствие starvation

bull FIFO

bull Честность в обмен на производительностьhttpgeecsoswegoedudlpapersaqspdf

37 copy JavaTechDays 2011 Oracle Corporation

Concurrencyатомарный счётчик

private AtomicInteger atomic = new AtomicInteger() private ReentrantLock lock = new ReentrantLock() private final Object intrinsicLock = new Object() private int primCounter = 0

GenerateMicroBenchmark public void testAtomicInteger() atomicincrementAndGet()

GenerateMicroBenchmark public void testReentrantLock() locklock() primCounter++ lockunlock()

GenerateMicroBenchmark public void testIntrinsicLock() synchronized (intrinsicLock) primCounter++

38 copy JavaTechDays 2011 Oracle Corporation

Concurrencyатомарный счётчик

0 16 32 48 64 80 96 112 128

1000

10000

100000

Atomic Counter Performance

Intrinsic AtomicInteger ReentrantLock

Threads

ops

sec

8x8 CPUs Solaris 6u25

39 copy JavaTechDays 2011 Oracle Corporation

ConcurrencyReentrantLock vs synchronized

bull Семантика одинаковаndash Требования к видимости памяти

ndash Рекурсивный

bull Плюсы jucRLndash Очередь потоков держится на стороне JVM

bull опционально FIFO-политика при захвате-освобождении

bull позволяет быть ldquoчестнымrdquo на любой платформе

ndash Barging FIFO policy

bull lock() может быть сразу удовлетворён даже если в очереди есть потоки

bull сильно улучшает производительность при конфликте блокировок

ndash Допускается несколько Condition

bull Минусы jucRLndash Нет scopeов требуется ручной unlock() через finally

bull Должно быть проще с ARM в JDK7

40 copy JavaTechDays 2011 Oracle Corporation

Concurrencyбесконфликтный захват

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

10000

20000

30000

40000

50000

60000

70000

80000

90000

100000

110000

120000

130000

140000

150000

Uncontended Lock Performance

intrinsic jucReentrantL (non-fair) jucReentrantL (fair)

Threads

op

sse

c

41 copy JavaTechDays 2011 Oracle Corporation

Concurrencyконфликтный захват

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

500

1000

1500

2000

2500

3000

3500

4000

4500

Contended Lock Performance

intrinsic jucReentrantL (non-fair) jucReentrantL (fair)

Threads

op

sse

c

43 copy 2011 JavaTechDays Oracle Corporation

bull hellip естьbull hellip работаетbull hellip работает хорошоbull hellip знает о железе всё

ndash Количество и тип CPUndash Поддерживаемые инcтрукции (SSEx AVX VIS)ndash Топологию памяти (в тч размеры кэшей и их характеристики)

bull hellip знает о приложении много всегоndash Иерархию загруженных классовndash Актуальную статистику создания объектовndash Горячий кодndash Какие ветвления исполнялисьndash Какие значения использовалисьndash Многое другое

bull hellip не боится использовать эти знания для компиляции

JITфакты

44 copy 2011 JavaTechDays Oracle Corporation

JITоптимизации

46 copy 2011 JavaTechDays Oracle Corporation

JITкак писать код

bull Используйте стандартные библиотекиndash Зачем писать собственный стандартный контейнер

bull Используйте высокоуровневый API ndash javautilndash javautilconcurrentndash NIO NIO2ndash вообще библиотеки

bull Код должен правильным и понятнымndash Сначала правильноndash Потом алгоритмически ldquoбыстроrdquondash Код не должен быть JIT-oriented

bull Правильно используйте возможности языкаndash EPIC FAIL штатная передача управления exceptionамиndash FAIL Возврат ldquoисключенияrdquo через return ltкод_ошибкиgtndash FAIL int вместо Enum или boolean

47 copy 2011 JavaTechDays Oracle Corporation

Как получить ассемблерный код метода

ndash Обычным дебаггером )

ndash JVMTI

ndash -XX+PrintAssemblybull httpwikissuncomdisplayHotSpotInternalsPrintAssembly

JITдля любопытных

54 copy JavaTechDays 2011 Oracle Corporation

StartupEclipse

bull Типичная конфигурацияndash 2x2 Intel i5 26 Ghz Ubuntu 1010 i686 JDK 6u25ndash Eclipse JDT (Galileo)

bull Типичные метрикиndash 6000 загруженных классовndash 1000 методов скомпилированоndash 512 Mb зарезервированного пространства в кучеndash 25 Mb кучи использовано после стартапа

bull Известные ldquoпроблемыrdquondash Загрузка и верификация классовndash JIT-компиляция

55 copy JavaTechDays 2011 Oracle Corporation

StartupEclipse

bull Метрика секунд на запуск-завершениеndash Файловые кеши прогреты практически нулевой дисковый IO

default CDS CDS + no-verify

абсолютное время

583 [574 592]

481[473 484]

461[456 474]

загрузка классов

501[491 511]

339[312 366]

301[294 308]

компиляция 051[043 059]

051[044 058]

051[042 060]

56 copy JavaTechDays 2011 Oracle Corporation

Startupдлинные приложения

bull Важно только для коротких приложенийndash Чем дольше работает приложение тем меньше удельные затраты на

загрузку классов и компиляцию

bull Пример 8 часа работает IntelliJ IDEA 10xndash 26600 классов загруженоndash 5315 методов скомпилировано

bull Загрузка классовndash Всего потрачено 202 с ~07 общего времениndash 10 мсек на класс

bull Компиляцияndash Всего потрачено 112 с ~003 общего времениndash 20 мсек на метод

57 copy JavaTechDays 2011 Oracle Corporation

Whats Next

bull Послушать ещёndash JavaOne Moscow (апрель 2011)

bull Проблема со слайдамиndash Найдите нас на конференцииndash Напишите нам письмо

bull Проблема с JDKndash httpopenjdkjavanetndash Задайте вопрос в OpenJDKndash а лучше сделайте патч и дайте его в OpenJDK на review

58 copy JavaTechDays 2011 Oracle Corporation

QA

Page 21: Java Platform Performance BoF - Aleksey Shipilëv · – 2x2 Intel i5 2.6 Ghz, Ubuntu 10.10 i686, JDK 6u25 • Три варианта эксперимента: – 1 экземпляр

27 copy JavaTechDays 2011 Oracle Corporation

hellip and beyondнастройка параметров JVM

bull Что настраиватьndash httpblogssuncomwattresourcejvm-options-listhtml

ndash httpwwworaclecomtechnetworkjavajavasetechvmoptions-jsp-140102html

bull JVM сама подбирает оптимальные параметры своей работыndash Server vs Client ndash Large pages (Solaris)ndash CompressedOops (64-bit VM)

bull Так что же настраиватьndash GCHeap tuningndash -XX+UseNUMA (Solaris Linux)ndash -XX+UseLargePages (Linux Windows)

bull httpwwworaclecomtechnetworkjavajavasetechlargememory-jsp-137182html

bull Не забытьndash Использовать последнюю версию JDK

29 copy JavaTechDays 2011 Oracle Corporation

Concurrencyэлементная база

bull OS Threadingndash мьютексы

bull mutex_lock()mutex_unlock()ndash conditional waits

bull cond_wait()cond_signal()bull WaitForSingleObject

bull Compare-and-Swap (CAS)ndash CAS(x1 x2 x3) = if (x1 == x2) x1 = x3 ndash атомарная операция поддерживаемая в ldquoжелезеrdquo из нескольких

одновременных CASов успешно завершается только одинndash Миф локальный CAS блокирует шину и стоит больше на

многопроцессорных системах ndash Факт глобальный CAS требует трафика на шине

httpblogssuncomdaveentrybiased_locking_in_hotspot

30 copy JavaTechDays 2011 Oracle Corporation

Concurrencyatomics

bull javautilconcurrentAtomicndash обеспечивают атомарные операции над примитивами и указателямиndash альтернатива synchronized или Lockи

bull Трюк в использовании CASаndash Изменение состояния атомика делается при помощи одного CASаndash Чтение состояния не требует CASа

public final int incrementAndGet() for () int current = get() int next = current + 1 if (compareAndSet(current next)) return next

mov ecxedxmov 0x8(ecx)eaxlea 0x8(ecx)edimov eaxecxinc ecxlock cmpxchg ecx(edi)mov $0x0ebxjne [ok]mov $0x1ebxtest ebxebxje [ok]

31 copy JavaTechDays 2011 Oracle Corporation

Concurrencyvolatile

bull Volatile определяет порядок чтения-записей в полеndash Точная семантика определена в Java Memory Model

bull НЕ обеспечивает атомарностиndash Реализуется расстановкой барьеров

bull Какие из них вставятся в код зависит от Hardware Memory Modelbull Эффект барьера зависит от HMM

PUSHL EBPSUB ESP8MOV EBX[ECX + 12]MEMBAR-acquireMEMBAR-releaseINC EBXMOV [ECX + 12]EBXMEMBAR-volatileLOCK ADDL [ESP + 0] 0ADD ESP8POPL EBPTEST PollPageEAXRET

push ebpsub $0x8espmov 0xc(ecx)ebxinc ebxmov ebx0xc(ecx)lock addl $0x0(esp)add $0x8esppop ebptest eax0xb779c000ret

httpgoswegoedudljmmcookbookhtml

32 copy JavaTechDays 2011 Oracle Corporation

Concurrencyvolatile-счётчик

public class VolatileTest

private int counter = 0 private volatile int volatileCounter = 0

GenerateMicroBenchmark public void testOrdinary() counter++

GenerateMicroBenchmark public void testVolatile() volatileCounter++

33 copy JavaTechDays 2011 Oracle Corporation

Concurrencyбесконфликтный volatile-счётчик

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

500000

1000000

1500000

2000000

2500000

3000000

3500000

Thread-local counter performance

ordinary volatile

Threads

op

ss

ec

34 copy JavaTechDays 2011 Oracle Corporation

Concurrencyконфликтный volatile-счётчик

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

100000

200000

300000

400000

500000

600000

700000

800000

900000

Global counter performance

ordinary volatile

Threads

op

ss

ec

35 copy JavaTechDays 2011 Oracle Corporation

Concurrencyintrinsic synchronization

bull synchronized(object) bull 4 состояния

ndash Initbull Начальное ldquoнеопределённоеrdquo состояние

ndash Biasedbull Захватывается одним ldquoвладеющимrdquo потоком нет конфликтовbull Захват владельцем проверка на threadIDbull Захват не-владельцем переход либо в Biased либо в Thin

ndash Thinbull Захватывается несколькими потоками но конфликтов нетbull Захват CASbull Конфликтный захват переход в Fat

ndash Fatbull Захватывается несколькими потоками конфликт на блокировкеbull Вызов примитива синхронизации из ОС

36 copy JavaTechDays 2011 Oracle Corporation

ConcurrencyjavautilconcurrentLock

bull Построены на базе jucAbstractQueueSynchronizerndash Использует атомики

bull CAS

ndash Использует Unsafepark()unpark()

bull интринзики для cond_wait()cond_signal()WaitForSingleObject()

bull ReentrantLockndash По семантике эквивалентен synchronized

bull Рекурсивный захват проверка на threadID

bull Ставит потоки во внутреннюю очередь и делает park()

ndash Non-Fair (default)

bull Не гарантирует отсутствие starvation

bull Barging FIFO (CAS)

bull Лучшая производительность

ndash Fair

bull Гарантирует отсутствие starvation

bull FIFO

bull Честность в обмен на производительностьhttpgeecsoswegoedudlpapersaqspdf

37 copy JavaTechDays 2011 Oracle Corporation

Concurrencyатомарный счётчик

private AtomicInteger atomic = new AtomicInteger() private ReentrantLock lock = new ReentrantLock() private final Object intrinsicLock = new Object() private int primCounter = 0

GenerateMicroBenchmark public void testAtomicInteger() atomicincrementAndGet()

GenerateMicroBenchmark public void testReentrantLock() locklock() primCounter++ lockunlock()

GenerateMicroBenchmark public void testIntrinsicLock() synchronized (intrinsicLock) primCounter++

38 copy JavaTechDays 2011 Oracle Corporation

Concurrencyатомарный счётчик

0 16 32 48 64 80 96 112 128

1000

10000

100000

Atomic Counter Performance

Intrinsic AtomicInteger ReentrantLock

Threads

ops

sec

8x8 CPUs Solaris 6u25

39 copy JavaTechDays 2011 Oracle Corporation

ConcurrencyReentrantLock vs synchronized

bull Семантика одинаковаndash Требования к видимости памяти

ndash Рекурсивный

bull Плюсы jucRLndash Очередь потоков держится на стороне JVM

bull опционально FIFO-политика при захвате-освобождении

bull позволяет быть ldquoчестнымrdquo на любой платформе

ndash Barging FIFO policy

bull lock() может быть сразу удовлетворён даже если в очереди есть потоки

bull сильно улучшает производительность при конфликте блокировок

ndash Допускается несколько Condition

bull Минусы jucRLndash Нет scopeов требуется ручной unlock() через finally

bull Должно быть проще с ARM в JDK7

40 copy JavaTechDays 2011 Oracle Corporation

Concurrencyбесконфликтный захват

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

10000

20000

30000

40000

50000

60000

70000

80000

90000

100000

110000

120000

130000

140000

150000

Uncontended Lock Performance

intrinsic jucReentrantL (non-fair) jucReentrantL (fair)

Threads

op

sse

c

41 copy JavaTechDays 2011 Oracle Corporation

Concurrencyконфликтный захват

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

500

1000

1500

2000

2500

3000

3500

4000

4500

Contended Lock Performance

intrinsic jucReentrantL (non-fair) jucReentrantL (fair)

Threads

op

sse

c

43 copy 2011 JavaTechDays Oracle Corporation

bull hellip естьbull hellip работаетbull hellip работает хорошоbull hellip знает о железе всё

ndash Количество и тип CPUndash Поддерживаемые инcтрукции (SSEx AVX VIS)ndash Топологию памяти (в тч размеры кэшей и их характеристики)

bull hellip знает о приложении много всегоndash Иерархию загруженных классовndash Актуальную статистику создания объектовndash Горячий кодndash Какие ветвления исполнялисьndash Какие значения использовалисьndash Многое другое

bull hellip не боится использовать эти знания для компиляции

JITфакты

44 copy 2011 JavaTechDays Oracle Corporation

JITоптимизации

46 copy 2011 JavaTechDays Oracle Corporation

JITкак писать код

bull Используйте стандартные библиотекиndash Зачем писать собственный стандартный контейнер

bull Используйте высокоуровневый API ndash javautilndash javautilconcurrentndash NIO NIO2ndash вообще библиотеки

bull Код должен правильным и понятнымndash Сначала правильноndash Потом алгоритмически ldquoбыстроrdquondash Код не должен быть JIT-oriented

bull Правильно используйте возможности языкаndash EPIC FAIL штатная передача управления exceptionамиndash FAIL Возврат ldquoисключенияrdquo через return ltкод_ошибкиgtndash FAIL int вместо Enum или boolean

47 copy 2011 JavaTechDays Oracle Corporation

Как получить ассемблерный код метода

ndash Обычным дебаггером )

ndash JVMTI

ndash -XX+PrintAssemblybull httpwikissuncomdisplayHotSpotInternalsPrintAssembly

JITдля любопытных

54 copy JavaTechDays 2011 Oracle Corporation

StartupEclipse

bull Типичная конфигурацияndash 2x2 Intel i5 26 Ghz Ubuntu 1010 i686 JDK 6u25ndash Eclipse JDT (Galileo)

bull Типичные метрикиndash 6000 загруженных классовndash 1000 методов скомпилированоndash 512 Mb зарезервированного пространства в кучеndash 25 Mb кучи использовано после стартапа

bull Известные ldquoпроблемыrdquondash Загрузка и верификация классовndash JIT-компиляция

55 copy JavaTechDays 2011 Oracle Corporation

StartupEclipse

bull Метрика секунд на запуск-завершениеndash Файловые кеши прогреты практически нулевой дисковый IO

default CDS CDS + no-verify

абсолютное время

583 [574 592]

481[473 484]

461[456 474]

загрузка классов

501[491 511]

339[312 366]

301[294 308]

компиляция 051[043 059]

051[044 058]

051[042 060]

56 copy JavaTechDays 2011 Oracle Corporation

Startupдлинные приложения

bull Важно только для коротких приложенийndash Чем дольше работает приложение тем меньше удельные затраты на

загрузку классов и компиляцию

bull Пример 8 часа работает IntelliJ IDEA 10xndash 26600 классов загруженоndash 5315 методов скомпилировано

bull Загрузка классовndash Всего потрачено 202 с ~07 общего времениndash 10 мсек на класс

bull Компиляцияndash Всего потрачено 112 с ~003 общего времениndash 20 мсек на метод

57 copy JavaTechDays 2011 Oracle Corporation

Whats Next

bull Послушать ещёndash JavaOne Moscow (апрель 2011)

bull Проблема со слайдамиndash Найдите нас на конференцииndash Напишите нам письмо

bull Проблема с JDKndash httpopenjdkjavanetndash Задайте вопрос в OpenJDKndash а лучше сделайте патч и дайте его в OpenJDK на review

58 copy JavaTechDays 2011 Oracle Corporation

QA

Page 22: Java Platform Performance BoF - Aleksey Shipilëv · – 2x2 Intel i5 2.6 Ghz, Ubuntu 10.10 i686, JDK 6u25 • Три варианта эксперимента: – 1 экземпляр

29 copy JavaTechDays 2011 Oracle Corporation

Concurrencyэлементная база

bull OS Threadingndash мьютексы

bull mutex_lock()mutex_unlock()ndash conditional waits

bull cond_wait()cond_signal()bull WaitForSingleObject

bull Compare-and-Swap (CAS)ndash CAS(x1 x2 x3) = if (x1 == x2) x1 = x3 ndash атомарная операция поддерживаемая в ldquoжелезеrdquo из нескольких

одновременных CASов успешно завершается только одинndash Миф локальный CAS блокирует шину и стоит больше на

многопроцессорных системах ndash Факт глобальный CAS требует трафика на шине

httpblogssuncomdaveentrybiased_locking_in_hotspot

30 copy JavaTechDays 2011 Oracle Corporation

Concurrencyatomics

bull javautilconcurrentAtomicndash обеспечивают атомарные операции над примитивами и указателямиndash альтернатива synchronized или Lockи

bull Трюк в использовании CASаndash Изменение состояния атомика делается при помощи одного CASаndash Чтение состояния не требует CASа

public final int incrementAndGet() for () int current = get() int next = current + 1 if (compareAndSet(current next)) return next

mov ecxedxmov 0x8(ecx)eaxlea 0x8(ecx)edimov eaxecxinc ecxlock cmpxchg ecx(edi)mov $0x0ebxjne [ok]mov $0x1ebxtest ebxebxje [ok]

31 copy JavaTechDays 2011 Oracle Corporation

Concurrencyvolatile

bull Volatile определяет порядок чтения-записей в полеndash Точная семантика определена в Java Memory Model

bull НЕ обеспечивает атомарностиndash Реализуется расстановкой барьеров

bull Какие из них вставятся в код зависит от Hardware Memory Modelbull Эффект барьера зависит от HMM

PUSHL EBPSUB ESP8MOV EBX[ECX + 12]MEMBAR-acquireMEMBAR-releaseINC EBXMOV [ECX + 12]EBXMEMBAR-volatileLOCK ADDL [ESP + 0] 0ADD ESP8POPL EBPTEST PollPageEAXRET

push ebpsub $0x8espmov 0xc(ecx)ebxinc ebxmov ebx0xc(ecx)lock addl $0x0(esp)add $0x8esppop ebptest eax0xb779c000ret

httpgoswegoedudljmmcookbookhtml

32 copy JavaTechDays 2011 Oracle Corporation

Concurrencyvolatile-счётчик

public class VolatileTest

private int counter = 0 private volatile int volatileCounter = 0

GenerateMicroBenchmark public void testOrdinary() counter++

GenerateMicroBenchmark public void testVolatile() volatileCounter++

33 copy JavaTechDays 2011 Oracle Corporation

Concurrencyбесконфликтный volatile-счётчик

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

500000

1000000

1500000

2000000

2500000

3000000

3500000

Thread-local counter performance

ordinary volatile

Threads

op

ss

ec

34 copy JavaTechDays 2011 Oracle Corporation

Concurrencyконфликтный volatile-счётчик

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

100000

200000

300000

400000

500000

600000

700000

800000

900000

Global counter performance

ordinary volatile

Threads

op

ss

ec

35 copy JavaTechDays 2011 Oracle Corporation

Concurrencyintrinsic synchronization

bull synchronized(object) bull 4 состояния

ndash Initbull Начальное ldquoнеопределённоеrdquo состояние

ndash Biasedbull Захватывается одним ldquoвладеющимrdquo потоком нет конфликтовbull Захват владельцем проверка на threadIDbull Захват не-владельцем переход либо в Biased либо в Thin

ndash Thinbull Захватывается несколькими потоками но конфликтов нетbull Захват CASbull Конфликтный захват переход в Fat

ndash Fatbull Захватывается несколькими потоками конфликт на блокировкеbull Вызов примитива синхронизации из ОС

36 copy JavaTechDays 2011 Oracle Corporation

ConcurrencyjavautilconcurrentLock

bull Построены на базе jucAbstractQueueSynchronizerndash Использует атомики

bull CAS

ndash Использует Unsafepark()unpark()

bull интринзики для cond_wait()cond_signal()WaitForSingleObject()

bull ReentrantLockndash По семантике эквивалентен synchronized

bull Рекурсивный захват проверка на threadID

bull Ставит потоки во внутреннюю очередь и делает park()

ndash Non-Fair (default)

bull Не гарантирует отсутствие starvation

bull Barging FIFO (CAS)

bull Лучшая производительность

ndash Fair

bull Гарантирует отсутствие starvation

bull FIFO

bull Честность в обмен на производительностьhttpgeecsoswegoedudlpapersaqspdf

37 copy JavaTechDays 2011 Oracle Corporation

Concurrencyатомарный счётчик

private AtomicInteger atomic = new AtomicInteger() private ReentrantLock lock = new ReentrantLock() private final Object intrinsicLock = new Object() private int primCounter = 0

GenerateMicroBenchmark public void testAtomicInteger() atomicincrementAndGet()

GenerateMicroBenchmark public void testReentrantLock() locklock() primCounter++ lockunlock()

GenerateMicroBenchmark public void testIntrinsicLock() synchronized (intrinsicLock) primCounter++

38 copy JavaTechDays 2011 Oracle Corporation

Concurrencyатомарный счётчик

0 16 32 48 64 80 96 112 128

1000

10000

100000

Atomic Counter Performance

Intrinsic AtomicInteger ReentrantLock

Threads

ops

sec

8x8 CPUs Solaris 6u25

39 copy JavaTechDays 2011 Oracle Corporation

ConcurrencyReentrantLock vs synchronized

bull Семантика одинаковаndash Требования к видимости памяти

ndash Рекурсивный

bull Плюсы jucRLndash Очередь потоков держится на стороне JVM

bull опционально FIFO-политика при захвате-освобождении

bull позволяет быть ldquoчестнымrdquo на любой платформе

ndash Barging FIFO policy

bull lock() может быть сразу удовлетворён даже если в очереди есть потоки

bull сильно улучшает производительность при конфликте блокировок

ndash Допускается несколько Condition

bull Минусы jucRLndash Нет scopeов требуется ручной unlock() через finally

bull Должно быть проще с ARM в JDK7

40 copy JavaTechDays 2011 Oracle Corporation

Concurrencyбесконфликтный захват

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

10000

20000

30000

40000

50000

60000

70000

80000

90000

100000

110000

120000

130000

140000

150000

Uncontended Lock Performance

intrinsic jucReentrantL (non-fair) jucReentrantL (fair)

Threads

op

sse

c

41 copy JavaTechDays 2011 Oracle Corporation

Concurrencyконфликтный захват

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

500

1000

1500

2000

2500

3000

3500

4000

4500

Contended Lock Performance

intrinsic jucReentrantL (non-fair) jucReentrantL (fair)

Threads

op

sse

c

43 copy 2011 JavaTechDays Oracle Corporation

bull hellip естьbull hellip работаетbull hellip работает хорошоbull hellip знает о железе всё

ndash Количество и тип CPUndash Поддерживаемые инcтрукции (SSEx AVX VIS)ndash Топологию памяти (в тч размеры кэшей и их характеристики)

bull hellip знает о приложении много всегоndash Иерархию загруженных классовndash Актуальную статистику создания объектовndash Горячий кодndash Какие ветвления исполнялисьndash Какие значения использовалисьndash Многое другое

bull hellip не боится использовать эти знания для компиляции

JITфакты

44 copy 2011 JavaTechDays Oracle Corporation

JITоптимизации

46 copy 2011 JavaTechDays Oracle Corporation

JITкак писать код

bull Используйте стандартные библиотекиndash Зачем писать собственный стандартный контейнер

bull Используйте высокоуровневый API ndash javautilndash javautilconcurrentndash NIO NIO2ndash вообще библиотеки

bull Код должен правильным и понятнымndash Сначала правильноndash Потом алгоритмически ldquoбыстроrdquondash Код не должен быть JIT-oriented

bull Правильно используйте возможности языкаndash EPIC FAIL штатная передача управления exceptionамиndash FAIL Возврат ldquoисключенияrdquo через return ltкод_ошибкиgtndash FAIL int вместо Enum или boolean

47 copy 2011 JavaTechDays Oracle Corporation

Как получить ассемблерный код метода

ndash Обычным дебаггером )

ndash JVMTI

ndash -XX+PrintAssemblybull httpwikissuncomdisplayHotSpotInternalsPrintAssembly

JITдля любопытных

54 copy JavaTechDays 2011 Oracle Corporation

StartupEclipse

bull Типичная конфигурацияndash 2x2 Intel i5 26 Ghz Ubuntu 1010 i686 JDK 6u25ndash Eclipse JDT (Galileo)

bull Типичные метрикиndash 6000 загруженных классовndash 1000 методов скомпилированоndash 512 Mb зарезервированного пространства в кучеndash 25 Mb кучи использовано после стартапа

bull Известные ldquoпроблемыrdquondash Загрузка и верификация классовndash JIT-компиляция

55 copy JavaTechDays 2011 Oracle Corporation

StartupEclipse

bull Метрика секунд на запуск-завершениеndash Файловые кеши прогреты практически нулевой дисковый IO

default CDS CDS + no-verify

абсолютное время

583 [574 592]

481[473 484]

461[456 474]

загрузка классов

501[491 511]

339[312 366]

301[294 308]

компиляция 051[043 059]

051[044 058]

051[042 060]

56 copy JavaTechDays 2011 Oracle Corporation

Startupдлинные приложения

bull Важно только для коротких приложенийndash Чем дольше работает приложение тем меньше удельные затраты на

загрузку классов и компиляцию

bull Пример 8 часа работает IntelliJ IDEA 10xndash 26600 классов загруженоndash 5315 методов скомпилировано

bull Загрузка классовndash Всего потрачено 202 с ~07 общего времениndash 10 мсек на класс

bull Компиляцияndash Всего потрачено 112 с ~003 общего времениndash 20 мсек на метод

57 copy JavaTechDays 2011 Oracle Corporation

Whats Next

bull Послушать ещёndash JavaOne Moscow (апрель 2011)

bull Проблема со слайдамиndash Найдите нас на конференцииndash Напишите нам письмо

bull Проблема с JDKndash httpopenjdkjavanetndash Задайте вопрос в OpenJDKndash а лучше сделайте патч и дайте его в OpenJDK на review

58 copy JavaTechDays 2011 Oracle Corporation

QA

Page 23: Java Platform Performance BoF - Aleksey Shipilëv · – 2x2 Intel i5 2.6 Ghz, Ubuntu 10.10 i686, JDK 6u25 • Три варианта эксперимента: – 1 экземпляр

30 copy JavaTechDays 2011 Oracle Corporation

Concurrencyatomics

bull javautilconcurrentAtomicndash обеспечивают атомарные операции над примитивами и указателямиndash альтернатива synchronized или Lockи

bull Трюк в использовании CASаndash Изменение состояния атомика делается при помощи одного CASаndash Чтение состояния не требует CASа

public final int incrementAndGet() for () int current = get() int next = current + 1 if (compareAndSet(current next)) return next

mov ecxedxmov 0x8(ecx)eaxlea 0x8(ecx)edimov eaxecxinc ecxlock cmpxchg ecx(edi)mov $0x0ebxjne [ok]mov $0x1ebxtest ebxebxje [ok]

31 copy JavaTechDays 2011 Oracle Corporation

Concurrencyvolatile

bull Volatile определяет порядок чтения-записей в полеndash Точная семантика определена в Java Memory Model

bull НЕ обеспечивает атомарностиndash Реализуется расстановкой барьеров

bull Какие из них вставятся в код зависит от Hardware Memory Modelbull Эффект барьера зависит от HMM

PUSHL EBPSUB ESP8MOV EBX[ECX + 12]MEMBAR-acquireMEMBAR-releaseINC EBXMOV [ECX + 12]EBXMEMBAR-volatileLOCK ADDL [ESP + 0] 0ADD ESP8POPL EBPTEST PollPageEAXRET

push ebpsub $0x8espmov 0xc(ecx)ebxinc ebxmov ebx0xc(ecx)lock addl $0x0(esp)add $0x8esppop ebptest eax0xb779c000ret

httpgoswegoedudljmmcookbookhtml

32 copy JavaTechDays 2011 Oracle Corporation

Concurrencyvolatile-счётчик

public class VolatileTest

private int counter = 0 private volatile int volatileCounter = 0

GenerateMicroBenchmark public void testOrdinary() counter++

GenerateMicroBenchmark public void testVolatile() volatileCounter++

33 copy JavaTechDays 2011 Oracle Corporation

Concurrencyбесконфликтный volatile-счётчик

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

500000

1000000

1500000

2000000

2500000

3000000

3500000

Thread-local counter performance

ordinary volatile

Threads

op

ss

ec

34 copy JavaTechDays 2011 Oracle Corporation

Concurrencyконфликтный volatile-счётчик

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

100000

200000

300000

400000

500000

600000

700000

800000

900000

Global counter performance

ordinary volatile

Threads

op

ss

ec

35 copy JavaTechDays 2011 Oracle Corporation

Concurrencyintrinsic synchronization

bull synchronized(object) bull 4 состояния

ndash Initbull Начальное ldquoнеопределённоеrdquo состояние

ndash Biasedbull Захватывается одним ldquoвладеющимrdquo потоком нет конфликтовbull Захват владельцем проверка на threadIDbull Захват не-владельцем переход либо в Biased либо в Thin

ndash Thinbull Захватывается несколькими потоками но конфликтов нетbull Захват CASbull Конфликтный захват переход в Fat

ndash Fatbull Захватывается несколькими потоками конфликт на блокировкеbull Вызов примитива синхронизации из ОС

36 copy JavaTechDays 2011 Oracle Corporation

ConcurrencyjavautilconcurrentLock

bull Построены на базе jucAbstractQueueSynchronizerndash Использует атомики

bull CAS

ndash Использует Unsafepark()unpark()

bull интринзики для cond_wait()cond_signal()WaitForSingleObject()

bull ReentrantLockndash По семантике эквивалентен synchronized

bull Рекурсивный захват проверка на threadID

bull Ставит потоки во внутреннюю очередь и делает park()

ndash Non-Fair (default)

bull Не гарантирует отсутствие starvation

bull Barging FIFO (CAS)

bull Лучшая производительность

ndash Fair

bull Гарантирует отсутствие starvation

bull FIFO

bull Честность в обмен на производительностьhttpgeecsoswegoedudlpapersaqspdf

37 copy JavaTechDays 2011 Oracle Corporation

Concurrencyатомарный счётчик

private AtomicInteger atomic = new AtomicInteger() private ReentrantLock lock = new ReentrantLock() private final Object intrinsicLock = new Object() private int primCounter = 0

GenerateMicroBenchmark public void testAtomicInteger() atomicincrementAndGet()

GenerateMicroBenchmark public void testReentrantLock() locklock() primCounter++ lockunlock()

GenerateMicroBenchmark public void testIntrinsicLock() synchronized (intrinsicLock) primCounter++

38 copy JavaTechDays 2011 Oracle Corporation

Concurrencyатомарный счётчик

0 16 32 48 64 80 96 112 128

1000

10000

100000

Atomic Counter Performance

Intrinsic AtomicInteger ReentrantLock

Threads

ops

sec

8x8 CPUs Solaris 6u25

39 copy JavaTechDays 2011 Oracle Corporation

ConcurrencyReentrantLock vs synchronized

bull Семантика одинаковаndash Требования к видимости памяти

ndash Рекурсивный

bull Плюсы jucRLndash Очередь потоков держится на стороне JVM

bull опционально FIFO-политика при захвате-освобождении

bull позволяет быть ldquoчестнымrdquo на любой платформе

ndash Barging FIFO policy

bull lock() может быть сразу удовлетворён даже если в очереди есть потоки

bull сильно улучшает производительность при конфликте блокировок

ndash Допускается несколько Condition

bull Минусы jucRLndash Нет scopeов требуется ручной unlock() через finally

bull Должно быть проще с ARM в JDK7

40 copy JavaTechDays 2011 Oracle Corporation

Concurrencyбесконфликтный захват

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

10000

20000

30000

40000

50000

60000

70000

80000

90000

100000

110000

120000

130000

140000

150000

Uncontended Lock Performance

intrinsic jucReentrantL (non-fair) jucReentrantL (fair)

Threads

op

sse

c

41 copy JavaTechDays 2011 Oracle Corporation

Concurrencyконфликтный захват

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

500

1000

1500

2000

2500

3000

3500

4000

4500

Contended Lock Performance

intrinsic jucReentrantL (non-fair) jucReentrantL (fair)

Threads

op

sse

c

43 copy 2011 JavaTechDays Oracle Corporation

bull hellip естьbull hellip работаетbull hellip работает хорошоbull hellip знает о железе всё

ndash Количество и тип CPUndash Поддерживаемые инcтрукции (SSEx AVX VIS)ndash Топологию памяти (в тч размеры кэшей и их характеристики)

bull hellip знает о приложении много всегоndash Иерархию загруженных классовndash Актуальную статистику создания объектовndash Горячий кодndash Какие ветвления исполнялисьndash Какие значения использовалисьndash Многое другое

bull hellip не боится использовать эти знания для компиляции

JITфакты

44 copy 2011 JavaTechDays Oracle Corporation

JITоптимизации

46 copy 2011 JavaTechDays Oracle Corporation

JITкак писать код

bull Используйте стандартные библиотекиndash Зачем писать собственный стандартный контейнер

bull Используйте высокоуровневый API ndash javautilndash javautilconcurrentndash NIO NIO2ndash вообще библиотеки

bull Код должен правильным и понятнымndash Сначала правильноndash Потом алгоритмически ldquoбыстроrdquondash Код не должен быть JIT-oriented

bull Правильно используйте возможности языкаndash EPIC FAIL штатная передача управления exceptionамиndash FAIL Возврат ldquoисключенияrdquo через return ltкод_ошибкиgtndash FAIL int вместо Enum или boolean

47 copy 2011 JavaTechDays Oracle Corporation

Как получить ассемблерный код метода

ndash Обычным дебаггером )

ndash JVMTI

ndash -XX+PrintAssemblybull httpwikissuncomdisplayHotSpotInternalsPrintAssembly

JITдля любопытных

54 copy JavaTechDays 2011 Oracle Corporation

StartupEclipse

bull Типичная конфигурацияndash 2x2 Intel i5 26 Ghz Ubuntu 1010 i686 JDK 6u25ndash Eclipse JDT (Galileo)

bull Типичные метрикиndash 6000 загруженных классовndash 1000 методов скомпилированоndash 512 Mb зарезервированного пространства в кучеndash 25 Mb кучи использовано после стартапа

bull Известные ldquoпроблемыrdquondash Загрузка и верификация классовndash JIT-компиляция

55 copy JavaTechDays 2011 Oracle Corporation

StartupEclipse

bull Метрика секунд на запуск-завершениеndash Файловые кеши прогреты практически нулевой дисковый IO

default CDS CDS + no-verify

абсолютное время

583 [574 592]

481[473 484]

461[456 474]

загрузка классов

501[491 511]

339[312 366]

301[294 308]

компиляция 051[043 059]

051[044 058]

051[042 060]

56 copy JavaTechDays 2011 Oracle Corporation

Startupдлинные приложения

bull Важно только для коротких приложенийndash Чем дольше работает приложение тем меньше удельные затраты на

загрузку классов и компиляцию

bull Пример 8 часа работает IntelliJ IDEA 10xndash 26600 классов загруженоndash 5315 методов скомпилировано

bull Загрузка классовndash Всего потрачено 202 с ~07 общего времениndash 10 мсек на класс

bull Компиляцияndash Всего потрачено 112 с ~003 общего времениndash 20 мсек на метод

57 copy JavaTechDays 2011 Oracle Corporation

Whats Next

bull Послушать ещёndash JavaOne Moscow (апрель 2011)

bull Проблема со слайдамиndash Найдите нас на конференцииndash Напишите нам письмо

bull Проблема с JDKndash httpopenjdkjavanetndash Задайте вопрос в OpenJDKndash а лучше сделайте патч и дайте его в OpenJDK на review

58 copy JavaTechDays 2011 Oracle Corporation

QA

Page 24: Java Platform Performance BoF - Aleksey Shipilëv · – 2x2 Intel i5 2.6 Ghz, Ubuntu 10.10 i686, JDK 6u25 • Три варианта эксперимента: – 1 экземпляр

31 copy JavaTechDays 2011 Oracle Corporation

Concurrencyvolatile

bull Volatile определяет порядок чтения-записей в полеndash Точная семантика определена в Java Memory Model

bull НЕ обеспечивает атомарностиndash Реализуется расстановкой барьеров

bull Какие из них вставятся в код зависит от Hardware Memory Modelbull Эффект барьера зависит от HMM

PUSHL EBPSUB ESP8MOV EBX[ECX + 12]MEMBAR-acquireMEMBAR-releaseINC EBXMOV [ECX + 12]EBXMEMBAR-volatileLOCK ADDL [ESP + 0] 0ADD ESP8POPL EBPTEST PollPageEAXRET

push ebpsub $0x8espmov 0xc(ecx)ebxinc ebxmov ebx0xc(ecx)lock addl $0x0(esp)add $0x8esppop ebptest eax0xb779c000ret

httpgoswegoedudljmmcookbookhtml

32 copy JavaTechDays 2011 Oracle Corporation

Concurrencyvolatile-счётчик

public class VolatileTest

private int counter = 0 private volatile int volatileCounter = 0

GenerateMicroBenchmark public void testOrdinary() counter++

GenerateMicroBenchmark public void testVolatile() volatileCounter++

33 copy JavaTechDays 2011 Oracle Corporation

Concurrencyбесконфликтный volatile-счётчик

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

500000

1000000

1500000

2000000

2500000

3000000

3500000

Thread-local counter performance

ordinary volatile

Threads

op

ss

ec

34 copy JavaTechDays 2011 Oracle Corporation

Concurrencyконфликтный volatile-счётчик

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

100000

200000

300000

400000

500000

600000

700000

800000

900000

Global counter performance

ordinary volatile

Threads

op

ss

ec

35 copy JavaTechDays 2011 Oracle Corporation

Concurrencyintrinsic synchronization

bull synchronized(object) bull 4 состояния

ndash Initbull Начальное ldquoнеопределённоеrdquo состояние

ndash Biasedbull Захватывается одним ldquoвладеющимrdquo потоком нет конфликтовbull Захват владельцем проверка на threadIDbull Захват не-владельцем переход либо в Biased либо в Thin

ndash Thinbull Захватывается несколькими потоками но конфликтов нетbull Захват CASbull Конфликтный захват переход в Fat

ndash Fatbull Захватывается несколькими потоками конфликт на блокировкеbull Вызов примитива синхронизации из ОС

36 copy JavaTechDays 2011 Oracle Corporation

ConcurrencyjavautilconcurrentLock

bull Построены на базе jucAbstractQueueSynchronizerndash Использует атомики

bull CAS

ndash Использует Unsafepark()unpark()

bull интринзики для cond_wait()cond_signal()WaitForSingleObject()

bull ReentrantLockndash По семантике эквивалентен synchronized

bull Рекурсивный захват проверка на threadID

bull Ставит потоки во внутреннюю очередь и делает park()

ndash Non-Fair (default)

bull Не гарантирует отсутствие starvation

bull Barging FIFO (CAS)

bull Лучшая производительность

ndash Fair

bull Гарантирует отсутствие starvation

bull FIFO

bull Честность в обмен на производительностьhttpgeecsoswegoedudlpapersaqspdf

37 copy JavaTechDays 2011 Oracle Corporation

Concurrencyатомарный счётчик

private AtomicInteger atomic = new AtomicInteger() private ReentrantLock lock = new ReentrantLock() private final Object intrinsicLock = new Object() private int primCounter = 0

GenerateMicroBenchmark public void testAtomicInteger() atomicincrementAndGet()

GenerateMicroBenchmark public void testReentrantLock() locklock() primCounter++ lockunlock()

GenerateMicroBenchmark public void testIntrinsicLock() synchronized (intrinsicLock) primCounter++

38 copy JavaTechDays 2011 Oracle Corporation

Concurrencyатомарный счётчик

0 16 32 48 64 80 96 112 128

1000

10000

100000

Atomic Counter Performance

Intrinsic AtomicInteger ReentrantLock

Threads

ops

sec

8x8 CPUs Solaris 6u25

39 copy JavaTechDays 2011 Oracle Corporation

ConcurrencyReentrantLock vs synchronized

bull Семантика одинаковаndash Требования к видимости памяти

ndash Рекурсивный

bull Плюсы jucRLndash Очередь потоков держится на стороне JVM

bull опционально FIFO-политика при захвате-освобождении

bull позволяет быть ldquoчестнымrdquo на любой платформе

ndash Barging FIFO policy

bull lock() может быть сразу удовлетворён даже если в очереди есть потоки

bull сильно улучшает производительность при конфликте блокировок

ndash Допускается несколько Condition

bull Минусы jucRLndash Нет scopeов требуется ручной unlock() через finally

bull Должно быть проще с ARM в JDK7

40 copy JavaTechDays 2011 Oracle Corporation

Concurrencyбесконфликтный захват

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

10000

20000

30000

40000

50000

60000

70000

80000

90000

100000

110000

120000

130000

140000

150000

Uncontended Lock Performance

intrinsic jucReentrantL (non-fair) jucReentrantL (fair)

Threads

op

sse

c

41 copy JavaTechDays 2011 Oracle Corporation

Concurrencyконфликтный захват

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

500

1000

1500

2000

2500

3000

3500

4000

4500

Contended Lock Performance

intrinsic jucReentrantL (non-fair) jucReentrantL (fair)

Threads

op

sse

c

43 copy 2011 JavaTechDays Oracle Corporation

bull hellip естьbull hellip работаетbull hellip работает хорошоbull hellip знает о железе всё

ndash Количество и тип CPUndash Поддерживаемые инcтрукции (SSEx AVX VIS)ndash Топологию памяти (в тч размеры кэшей и их характеристики)

bull hellip знает о приложении много всегоndash Иерархию загруженных классовndash Актуальную статистику создания объектовndash Горячий кодndash Какие ветвления исполнялисьndash Какие значения использовалисьndash Многое другое

bull hellip не боится использовать эти знания для компиляции

JITфакты

44 copy 2011 JavaTechDays Oracle Corporation

JITоптимизации

46 copy 2011 JavaTechDays Oracle Corporation

JITкак писать код

bull Используйте стандартные библиотекиndash Зачем писать собственный стандартный контейнер

bull Используйте высокоуровневый API ndash javautilndash javautilconcurrentndash NIO NIO2ndash вообще библиотеки

bull Код должен правильным и понятнымndash Сначала правильноndash Потом алгоритмически ldquoбыстроrdquondash Код не должен быть JIT-oriented

bull Правильно используйте возможности языкаndash EPIC FAIL штатная передача управления exceptionамиndash FAIL Возврат ldquoисключенияrdquo через return ltкод_ошибкиgtndash FAIL int вместо Enum или boolean

47 copy 2011 JavaTechDays Oracle Corporation

Как получить ассемблерный код метода

ndash Обычным дебаггером )

ndash JVMTI

ndash -XX+PrintAssemblybull httpwikissuncomdisplayHotSpotInternalsPrintAssembly

JITдля любопытных

54 copy JavaTechDays 2011 Oracle Corporation

StartupEclipse

bull Типичная конфигурацияndash 2x2 Intel i5 26 Ghz Ubuntu 1010 i686 JDK 6u25ndash Eclipse JDT (Galileo)

bull Типичные метрикиndash 6000 загруженных классовndash 1000 методов скомпилированоndash 512 Mb зарезервированного пространства в кучеndash 25 Mb кучи использовано после стартапа

bull Известные ldquoпроблемыrdquondash Загрузка и верификация классовndash JIT-компиляция

55 copy JavaTechDays 2011 Oracle Corporation

StartupEclipse

bull Метрика секунд на запуск-завершениеndash Файловые кеши прогреты практически нулевой дисковый IO

default CDS CDS + no-verify

абсолютное время

583 [574 592]

481[473 484]

461[456 474]

загрузка классов

501[491 511]

339[312 366]

301[294 308]

компиляция 051[043 059]

051[044 058]

051[042 060]

56 copy JavaTechDays 2011 Oracle Corporation

Startupдлинные приложения

bull Важно только для коротких приложенийndash Чем дольше работает приложение тем меньше удельные затраты на

загрузку классов и компиляцию

bull Пример 8 часа работает IntelliJ IDEA 10xndash 26600 классов загруженоndash 5315 методов скомпилировано

bull Загрузка классовndash Всего потрачено 202 с ~07 общего времениndash 10 мсек на класс

bull Компиляцияndash Всего потрачено 112 с ~003 общего времениndash 20 мсек на метод

57 copy JavaTechDays 2011 Oracle Corporation

Whats Next

bull Послушать ещёndash JavaOne Moscow (апрель 2011)

bull Проблема со слайдамиndash Найдите нас на конференцииndash Напишите нам письмо

bull Проблема с JDKndash httpopenjdkjavanetndash Задайте вопрос в OpenJDKndash а лучше сделайте патч и дайте его в OpenJDK на review

58 copy JavaTechDays 2011 Oracle Corporation

QA

Page 25: Java Platform Performance BoF - Aleksey Shipilëv · – 2x2 Intel i5 2.6 Ghz, Ubuntu 10.10 i686, JDK 6u25 • Три варианта эксперимента: – 1 экземпляр

32 copy JavaTechDays 2011 Oracle Corporation

Concurrencyvolatile-счётчик

public class VolatileTest

private int counter = 0 private volatile int volatileCounter = 0

GenerateMicroBenchmark public void testOrdinary() counter++

GenerateMicroBenchmark public void testVolatile() volatileCounter++

33 copy JavaTechDays 2011 Oracle Corporation

Concurrencyбесконфликтный volatile-счётчик

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

500000

1000000

1500000

2000000

2500000

3000000

3500000

Thread-local counter performance

ordinary volatile

Threads

op

ss

ec

34 copy JavaTechDays 2011 Oracle Corporation

Concurrencyконфликтный volatile-счётчик

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

100000

200000

300000

400000

500000

600000

700000

800000

900000

Global counter performance

ordinary volatile

Threads

op

ss

ec

35 copy JavaTechDays 2011 Oracle Corporation

Concurrencyintrinsic synchronization

bull synchronized(object) bull 4 состояния

ndash Initbull Начальное ldquoнеопределённоеrdquo состояние

ndash Biasedbull Захватывается одним ldquoвладеющимrdquo потоком нет конфликтовbull Захват владельцем проверка на threadIDbull Захват не-владельцем переход либо в Biased либо в Thin

ndash Thinbull Захватывается несколькими потоками но конфликтов нетbull Захват CASbull Конфликтный захват переход в Fat

ndash Fatbull Захватывается несколькими потоками конфликт на блокировкеbull Вызов примитива синхронизации из ОС

36 copy JavaTechDays 2011 Oracle Corporation

ConcurrencyjavautilconcurrentLock

bull Построены на базе jucAbstractQueueSynchronizerndash Использует атомики

bull CAS

ndash Использует Unsafepark()unpark()

bull интринзики для cond_wait()cond_signal()WaitForSingleObject()

bull ReentrantLockndash По семантике эквивалентен synchronized

bull Рекурсивный захват проверка на threadID

bull Ставит потоки во внутреннюю очередь и делает park()

ndash Non-Fair (default)

bull Не гарантирует отсутствие starvation

bull Barging FIFO (CAS)

bull Лучшая производительность

ndash Fair

bull Гарантирует отсутствие starvation

bull FIFO

bull Честность в обмен на производительностьhttpgeecsoswegoedudlpapersaqspdf

37 copy JavaTechDays 2011 Oracle Corporation

Concurrencyатомарный счётчик

private AtomicInteger atomic = new AtomicInteger() private ReentrantLock lock = new ReentrantLock() private final Object intrinsicLock = new Object() private int primCounter = 0

GenerateMicroBenchmark public void testAtomicInteger() atomicincrementAndGet()

GenerateMicroBenchmark public void testReentrantLock() locklock() primCounter++ lockunlock()

GenerateMicroBenchmark public void testIntrinsicLock() synchronized (intrinsicLock) primCounter++

38 copy JavaTechDays 2011 Oracle Corporation

Concurrencyатомарный счётчик

0 16 32 48 64 80 96 112 128

1000

10000

100000

Atomic Counter Performance

Intrinsic AtomicInteger ReentrantLock

Threads

ops

sec

8x8 CPUs Solaris 6u25

39 copy JavaTechDays 2011 Oracle Corporation

ConcurrencyReentrantLock vs synchronized

bull Семантика одинаковаndash Требования к видимости памяти

ndash Рекурсивный

bull Плюсы jucRLndash Очередь потоков держится на стороне JVM

bull опционально FIFO-политика при захвате-освобождении

bull позволяет быть ldquoчестнымrdquo на любой платформе

ndash Barging FIFO policy

bull lock() может быть сразу удовлетворён даже если в очереди есть потоки

bull сильно улучшает производительность при конфликте блокировок

ndash Допускается несколько Condition

bull Минусы jucRLndash Нет scopeов требуется ручной unlock() через finally

bull Должно быть проще с ARM в JDK7

40 copy JavaTechDays 2011 Oracle Corporation

Concurrencyбесконфликтный захват

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

10000

20000

30000

40000

50000

60000

70000

80000

90000

100000

110000

120000

130000

140000

150000

Uncontended Lock Performance

intrinsic jucReentrantL (non-fair) jucReentrantL (fair)

Threads

op

sse

c

41 copy JavaTechDays 2011 Oracle Corporation

Concurrencyконфликтный захват

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

500

1000

1500

2000

2500

3000

3500

4000

4500

Contended Lock Performance

intrinsic jucReentrantL (non-fair) jucReentrantL (fair)

Threads

op

sse

c

43 copy 2011 JavaTechDays Oracle Corporation

bull hellip естьbull hellip работаетbull hellip работает хорошоbull hellip знает о железе всё

ndash Количество и тип CPUndash Поддерживаемые инcтрукции (SSEx AVX VIS)ndash Топологию памяти (в тч размеры кэшей и их характеристики)

bull hellip знает о приложении много всегоndash Иерархию загруженных классовndash Актуальную статистику создания объектовndash Горячий кодndash Какие ветвления исполнялисьndash Какие значения использовалисьndash Многое другое

bull hellip не боится использовать эти знания для компиляции

JITфакты

44 copy 2011 JavaTechDays Oracle Corporation

JITоптимизации

46 copy 2011 JavaTechDays Oracle Corporation

JITкак писать код

bull Используйте стандартные библиотекиndash Зачем писать собственный стандартный контейнер

bull Используйте высокоуровневый API ndash javautilndash javautilconcurrentndash NIO NIO2ndash вообще библиотеки

bull Код должен правильным и понятнымndash Сначала правильноndash Потом алгоритмически ldquoбыстроrdquondash Код не должен быть JIT-oriented

bull Правильно используйте возможности языкаndash EPIC FAIL штатная передача управления exceptionамиndash FAIL Возврат ldquoисключенияrdquo через return ltкод_ошибкиgtndash FAIL int вместо Enum или boolean

47 copy 2011 JavaTechDays Oracle Corporation

Как получить ассемблерный код метода

ndash Обычным дебаггером )

ndash JVMTI

ndash -XX+PrintAssemblybull httpwikissuncomdisplayHotSpotInternalsPrintAssembly

JITдля любопытных

54 copy JavaTechDays 2011 Oracle Corporation

StartupEclipse

bull Типичная конфигурацияndash 2x2 Intel i5 26 Ghz Ubuntu 1010 i686 JDK 6u25ndash Eclipse JDT (Galileo)

bull Типичные метрикиndash 6000 загруженных классовndash 1000 методов скомпилированоndash 512 Mb зарезервированного пространства в кучеndash 25 Mb кучи использовано после стартапа

bull Известные ldquoпроблемыrdquondash Загрузка и верификация классовndash JIT-компиляция

55 copy JavaTechDays 2011 Oracle Corporation

StartupEclipse

bull Метрика секунд на запуск-завершениеndash Файловые кеши прогреты практически нулевой дисковый IO

default CDS CDS + no-verify

абсолютное время

583 [574 592]

481[473 484]

461[456 474]

загрузка классов

501[491 511]

339[312 366]

301[294 308]

компиляция 051[043 059]

051[044 058]

051[042 060]

56 copy JavaTechDays 2011 Oracle Corporation

Startupдлинные приложения

bull Важно только для коротких приложенийndash Чем дольше работает приложение тем меньше удельные затраты на

загрузку классов и компиляцию

bull Пример 8 часа работает IntelliJ IDEA 10xndash 26600 классов загруженоndash 5315 методов скомпилировано

bull Загрузка классовndash Всего потрачено 202 с ~07 общего времениndash 10 мсек на класс

bull Компиляцияndash Всего потрачено 112 с ~003 общего времениndash 20 мсек на метод

57 copy JavaTechDays 2011 Oracle Corporation

Whats Next

bull Послушать ещёndash JavaOne Moscow (апрель 2011)

bull Проблема со слайдамиndash Найдите нас на конференцииndash Напишите нам письмо

bull Проблема с JDKndash httpopenjdkjavanetndash Задайте вопрос в OpenJDKndash а лучше сделайте патч и дайте его в OpenJDK на review

58 copy JavaTechDays 2011 Oracle Corporation

QA

Page 26: Java Platform Performance BoF - Aleksey Shipilëv · – 2x2 Intel i5 2.6 Ghz, Ubuntu 10.10 i686, JDK 6u25 • Три варианта эксперимента: – 1 экземпляр

33 copy JavaTechDays 2011 Oracle Corporation

Concurrencyбесконфликтный volatile-счётчик

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

500000

1000000

1500000

2000000

2500000

3000000

3500000

Thread-local counter performance

ordinary volatile

Threads

op

ss

ec

34 copy JavaTechDays 2011 Oracle Corporation

Concurrencyконфликтный volatile-счётчик

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

100000

200000

300000

400000

500000

600000

700000

800000

900000

Global counter performance

ordinary volatile

Threads

op

ss

ec

35 copy JavaTechDays 2011 Oracle Corporation

Concurrencyintrinsic synchronization

bull synchronized(object) bull 4 состояния

ndash Initbull Начальное ldquoнеопределённоеrdquo состояние

ndash Biasedbull Захватывается одним ldquoвладеющимrdquo потоком нет конфликтовbull Захват владельцем проверка на threadIDbull Захват не-владельцем переход либо в Biased либо в Thin

ndash Thinbull Захватывается несколькими потоками но конфликтов нетbull Захват CASbull Конфликтный захват переход в Fat

ndash Fatbull Захватывается несколькими потоками конфликт на блокировкеbull Вызов примитива синхронизации из ОС

36 copy JavaTechDays 2011 Oracle Corporation

ConcurrencyjavautilconcurrentLock

bull Построены на базе jucAbstractQueueSynchronizerndash Использует атомики

bull CAS

ndash Использует Unsafepark()unpark()

bull интринзики для cond_wait()cond_signal()WaitForSingleObject()

bull ReentrantLockndash По семантике эквивалентен synchronized

bull Рекурсивный захват проверка на threadID

bull Ставит потоки во внутреннюю очередь и делает park()

ndash Non-Fair (default)

bull Не гарантирует отсутствие starvation

bull Barging FIFO (CAS)

bull Лучшая производительность

ndash Fair

bull Гарантирует отсутствие starvation

bull FIFO

bull Честность в обмен на производительностьhttpgeecsoswegoedudlpapersaqspdf

37 copy JavaTechDays 2011 Oracle Corporation

Concurrencyатомарный счётчик

private AtomicInteger atomic = new AtomicInteger() private ReentrantLock lock = new ReentrantLock() private final Object intrinsicLock = new Object() private int primCounter = 0

GenerateMicroBenchmark public void testAtomicInteger() atomicincrementAndGet()

GenerateMicroBenchmark public void testReentrantLock() locklock() primCounter++ lockunlock()

GenerateMicroBenchmark public void testIntrinsicLock() synchronized (intrinsicLock) primCounter++

38 copy JavaTechDays 2011 Oracle Corporation

Concurrencyатомарный счётчик

0 16 32 48 64 80 96 112 128

1000

10000

100000

Atomic Counter Performance

Intrinsic AtomicInteger ReentrantLock

Threads

ops

sec

8x8 CPUs Solaris 6u25

39 copy JavaTechDays 2011 Oracle Corporation

ConcurrencyReentrantLock vs synchronized

bull Семантика одинаковаndash Требования к видимости памяти

ndash Рекурсивный

bull Плюсы jucRLndash Очередь потоков держится на стороне JVM

bull опционально FIFO-политика при захвате-освобождении

bull позволяет быть ldquoчестнымrdquo на любой платформе

ndash Barging FIFO policy

bull lock() может быть сразу удовлетворён даже если в очереди есть потоки

bull сильно улучшает производительность при конфликте блокировок

ndash Допускается несколько Condition

bull Минусы jucRLndash Нет scopeов требуется ручной unlock() через finally

bull Должно быть проще с ARM в JDK7

40 copy JavaTechDays 2011 Oracle Corporation

Concurrencyбесконфликтный захват

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

10000

20000

30000

40000

50000

60000

70000

80000

90000

100000

110000

120000

130000

140000

150000

Uncontended Lock Performance

intrinsic jucReentrantL (non-fair) jucReentrantL (fair)

Threads

op

sse

c

41 copy JavaTechDays 2011 Oracle Corporation

Concurrencyконфликтный захват

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

500

1000

1500

2000

2500

3000

3500

4000

4500

Contended Lock Performance

intrinsic jucReentrantL (non-fair) jucReentrantL (fair)

Threads

op

sse

c

43 copy 2011 JavaTechDays Oracle Corporation

bull hellip естьbull hellip работаетbull hellip работает хорошоbull hellip знает о железе всё

ndash Количество и тип CPUndash Поддерживаемые инcтрукции (SSEx AVX VIS)ndash Топологию памяти (в тч размеры кэшей и их характеристики)

bull hellip знает о приложении много всегоndash Иерархию загруженных классовndash Актуальную статистику создания объектовndash Горячий кодndash Какие ветвления исполнялисьndash Какие значения использовалисьndash Многое другое

bull hellip не боится использовать эти знания для компиляции

JITфакты

44 copy 2011 JavaTechDays Oracle Corporation

JITоптимизации

46 copy 2011 JavaTechDays Oracle Corporation

JITкак писать код

bull Используйте стандартные библиотекиndash Зачем писать собственный стандартный контейнер

bull Используйте высокоуровневый API ndash javautilndash javautilconcurrentndash NIO NIO2ndash вообще библиотеки

bull Код должен правильным и понятнымndash Сначала правильноndash Потом алгоритмически ldquoбыстроrdquondash Код не должен быть JIT-oriented

bull Правильно используйте возможности языкаndash EPIC FAIL штатная передача управления exceptionамиndash FAIL Возврат ldquoисключенияrdquo через return ltкод_ошибкиgtndash FAIL int вместо Enum или boolean

47 copy 2011 JavaTechDays Oracle Corporation

Как получить ассемблерный код метода

ndash Обычным дебаггером )

ndash JVMTI

ndash -XX+PrintAssemblybull httpwikissuncomdisplayHotSpotInternalsPrintAssembly

JITдля любопытных

54 copy JavaTechDays 2011 Oracle Corporation

StartupEclipse

bull Типичная конфигурацияndash 2x2 Intel i5 26 Ghz Ubuntu 1010 i686 JDK 6u25ndash Eclipse JDT (Galileo)

bull Типичные метрикиndash 6000 загруженных классовndash 1000 методов скомпилированоndash 512 Mb зарезервированного пространства в кучеndash 25 Mb кучи использовано после стартапа

bull Известные ldquoпроблемыrdquondash Загрузка и верификация классовndash JIT-компиляция

55 copy JavaTechDays 2011 Oracle Corporation

StartupEclipse

bull Метрика секунд на запуск-завершениеndash Файловые кеши прогреты практически нулевой дисковый IO

default CDS CDS + no-verify

абсолютное время

583 [574 592]

481[473 484]

461[456 474]

загрузка классов

501[491 511]

339[312 366]

301[294 308]

компиляция 051[043 059]

051[044 058]

051[042 060]

56 copy JavaTechDays 2011 Oracle Corporation

Startupдлинные приложения

bull Важно только для коротких приложенийndash Чем дольше работает приложение тем меньше удельные затраты на

загрузку классов и компиляцию

bull Пример 8 часа работает IntelliJ IDEA 10xndash 26600 классов загруженоndash 5315 методов скомпилировано

bull Загрузка классовndash Всего потрачено 202 с ~07 общего времениndash 10 мсек на класс

bull Компиляцияndash Всего потрачено 112 с ~003 общего времениndash 20 мсек на метод

57 copy JavaTechDays 2011 Oracle Corporation

Whats Next

bull Послушать ещёndash JavaOne Moscow (апрель 2011)

bull Проблема со слайдамиndash Найдите нас на конференцииndash Напишите нам письмо

bull Проблема с JDKndash httpopenjdkjavanetndash Задайте вопрос в OpenJDKndash а лучше сделайте патч и дайте его в OpenJDK на review

58 copy JavaTechDays 2011 Oracle Corporation

QA

Page 27: Java Platform Performance BoF - Aleksey Shipilëv · – 2x2 Intel i5 2.6 Ghz, Ubuntu 10.10 i686, JDK 6u25 • Три варианта эксперимента: – 1 экземпляр

34 copy JavaTechDays 2011 Oracle Corporation

Concurrencyконфликтный volatile-счётчик

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

100000

200000

300000

400000

500000

600000

700000

800000

900000

Global counter performance

ordinary volatile

Threads

op

ss

ec

35 copy JavaTechDays 2011 Oracle Corporation

Concurrencyintrinsic synchronization

bull synchronized(object) bull 4 состояния

ndash Initbull Начальное ldquoнеопределённоеrdquo состояние

ndash Biasedbull Захватывается одним ldquoвладеющимrdquo потоком нет конфликтовbull Захват владельцем проверка на threadIDbull Захват не-владельцем переход либо в Biased либо в Thin

ndash Thinbull Захватывается несколькими потоками но конфликтов нетbull Захват CASbull Конфликтный захват переход в Fat

ndash Fatbull Захватывается несколькими потоками конфликт на блокировкеbull Вызов примитива синхронизации из ОС

36 copy JavaTechDays 2011 Oracle Corporation

ConcurrencyjavautilconcurrentLock

bull Построены на базе jucAbstractQueueSynchronizerndash Использует атомики

bull CAS

ndash Использует Unsafepark()unpark()

bull интринзики для cond_wait()cond_signal()WaitForSingleObject()

bull ReentrantLockndash По семантике эквивалентен synchronized

bull Рекурсивный захват проверка на threadID

bull Ставит потоки во внутреннюю очередь и делает park()

ndash Non-Fair (default)

bull Не гарантирует отсутствие starvation

bull Barging FIFO (CAS)

bull Лучшая производительность

ndash Fair

bull Гарантирует отсутствие starvation

bull FIFO

bull Честность в обмен на производительностьhttpgeecsoswegoedudlpapersaqspdf

37 copy JavaTechDays 2011 Oracle Corporation

Concurrencyатомарный счётчик

private AtomicInteger atomic = new AtomicInteger() private ReentrantLock lock = new ReentrantLock() private final Object intrinsicLock = new Object() private int primCounter = 0

GenerateMicroBenchmark public void testAtomicInteger() atomicincrementAndGet()

GenerateMicroBenchmark public void testReentrantLock() locklock() primCounter++ lockunlock()

GenerateMicroBenchmark public void testIntrinsicLock() synchronized (intrinsicLock) primCounter++

38 copy JavaTechDays 2011 Oracle Corporation

Concurrencyатомарный счётчик

0 16 32 48 64 80 96 112 128

1000

10000

100000

Atomic Counter Performance

Intrinsic AtomicInteger ReentrantLock

Threads

ops

sec

8x8 CPUs Solaris 6u25

39 copy JavaTechDays 2011 Oracle Corporation

ConcurrencyReentrantLock vs synchronized

bull Семантика одинаковаndash Требования к видимости памяти

ndash Рекурсивный

bull Плюсы jucRLndash Очередь потоков держится на стороне JVM

bull опционально FIFO-политика при захвате-освобождении

bull позволяет быть ldquoчестнымrdquo на любой платформе

ndash Barging FIFO policy

bull lock() может быть сразу удовлетворён даже если в очереди есть потоки

bull сильно улучшает производительность при конфликте блокировок

ndash Допускается несколько Condition

bull Минусы jucRLndash Нет scopeов требуется ручной unlock() через finally

bull Должно быть проще с ARM в JDK7

40 copy JavaTechDays 2011 Oracle Corporation

Concurrencyбесконфликтный захват

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

10000

20000

30000

40000

50000

60000

70000

80000

90000

100000

110000

120000

130000

140000

150000

Uncontended Lock Performance

intrinsic jucReentrantL (non-fair) jucReentrantL (fair)

Threads

op

sse

c

41 copy JavaTechDays 2011 Oracle Corporation

Concurrencyконфликтный захват

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

500

1000

1500

2000

2500

3000

3500

4000

4500

Contended Lock Performance

intrinsic jucReentrantL (non-fair) jucReentrantL (fair)

Threads

op

sse

c

43 copy 2011 JavaTechDays Oracle Corporation

bull hellip естьbull hellip работаетbull hellip работает хорошоbull hellip знает о железе всё

ndash Количество и тип CPUndash Поддерживаемые инcтрукции (SSEx AVX VIS)ndash Топологию памяти (в тч размеры кэшей и их характеристики)

bull hellip знает о приложении много всегоndash Иерархию загруженных классовndash Актуальную статистику создания объектовndash Горячий кодndash Какие ветвления исполнялисьndash Какие значения использовалисьndash Многое другое

bull hellip не боится использовать эти знания для компиляции

JITфакты

44 copy 2011 JavaTechDays Oracle Corporation

JITоптимизации

46 copy 2011 JavaTechDays Oracle Corporation

JITкак писать код

bull Используйте стандартные библиотекиndash Зачем писать собственный стандартный контейнер

bull Используйте высокоуровневый API ndash javautilndash javautilconcurrentndash NIO NIO2ndash вообще библиотеки

bull Код должен правильным и понятнымndash Сначала правильноndash Потом алгоритмически ldquoбыстроrdquondash Код не должен быть JIT-oriented

bull Правильно используйте возможности языкаndash EPIC FAIL штатная передача управления exceptionамиndash FAIL Возврат ldquoисключенияrdquo через return ltкод_ошибкиgtndash FAIL int вместо Enum или boolean

47 copy 2011 JavaTechDays Oracle Corporation

Как получить ассемблерный код метода

ndash Обычным дебаггером )

ndash JVMTI

ndash -XX+PrintAssemblybull httpwikissuncomdisplayHotSpotInternalsPrintAssembly

JITдля любопытных

54 copy JavaTechDays 2011 Oracle Corporation

StartupEclipse

bull Типичная конфигурацияndash 2x2 Intel i5 26 Ghz Ubuntu 1010 i686 JDK 6u25ndash Eclipse JDT (Galileo)

bull Типичные метрикиndash 6000 загруженных классовndash 1000 методов скомпилированоndash 512 Mb зарезервированного пространства в кучеndash 25 Mb кучи использовано после стартапа

bull Известные ldquoпроблемыrdquondash Загрузка и верификация классовndash JIT-компиляция

55 copy JavaTechDays 2011 Oracle Corporation

StartupEclipse

bull Метрика секунд на запуск-завершениеndash Файловые кеши прогреты практически нулевой дисковый IO

default CDS CDS + no-verify

абсолютное время

583 [574 592]

481[473 484]

461[456 474]

загрузка классов

501[491 511]

339[312 366]

301[294 308]

компиляция 051[043 059]

051[044 058]

051[042 060]

56 copy JavaTechDays 2011 Oracle Corporation

Startupдлинные приложения

bull Важно только для коротких приложенийndash Чем дольше работает приложение тем меньше удельные затраты на

загрузку классов и компиляцию

bull Пример 8 часа работает IntelliJ IDEA 10xndash 26600 классов загруженоndash 5315 методов скомпилировано

bull Загрузка классовndash Всего потрачено 202 с ~07 общего времениndash 10 мсек на класс

bull Компиляцияndash Всего потрачено 112 с ~003 общего времениndash 20 мсек на метод

57 copy JavaTechDays 2011 Oracle Corporation

Whats Next

bull Послушать ещёndash JavaOne Moscow (апрель 2011)

bull Проблема со слайдамиndash Найдите нас на конференцииndash Напишите нам письмо

bull Проблема с JDKndash httpopenjdkjavanetndash Задайте вопрос в OpenJDKndash а лучше сделайте патч и дайте его в OpenJDK на review

58 copy JavaTechDays 2011 Oracle Corporation

QA

Page 28: Java Platform Performance BoF - Aleksey Shipilëv · – 2x2 Intel i5 2.6 Ghz, Ubuntu 10.10 i686, JDK 6u25 • Три варианта эксперимента: – 1 экземпляр

35 copy JavaTechDays 2011 Oracle Corporation

Concurrencyintrinsic synchronization

bull synchronized(object) bull 4 состояния

ndash Initbull Начальное ldquoнеопределённоеrdquo состояние

ndash Biasedbull Захватывается одним ldquoвладеющимrdquo потоком нет конфликтовbull Захват владельцем проверка на threadIDbull Захват не-владельцем переход либо в Biased либо в Thin

ndash Thinbull Захватывается несколькими потоками но конфликтов нетbull Захват CASbull Конфликтный захват переход в Fat

ndash Fatbull Захватывается несколькими потоками конфликт на блокировкеbull Вызов примитива синхронизации из ОС

36 copy JavaTechDays 2011 Oracle Corporation

ConcurrencyjavautilconcurrentLock

bull Построены на базе jucAbstractQueueSynchronizerndash Использует атомики

bull CAS

ndash Использует Unsafepark()unpark()

bull интринзики для cond_wait()cond_signal()WaitForSingleObject()

bull ReentrantLockndash По семантике эквивалентен synchronized

bull Рекурсивный захват проверка на threadID

bull Ставит потоки во внутреннюю очередь и делает park()

ndash Non-Fair (default)

bull Не гарантирует отсутствие starvation

bull Barging FIFO (CAS)

bull Лучшая производительность

ndash Fair

bull Гарантирует отсутствие starvation

bull FIFO

bull Честность в обмен на производительностьhttpgeecsoswegoedudlpapersaqspdf

37 copy JavaTechDays 2011 Oracle Corporation

Concurrencyатомарный счётчик

private AtomicInteger atomic = new AtomicInteger() private ReentrantLock lock = new ReentrantLock() private final Object intrinsicLock = new Object() private int primCounter = 0

GenerateMicroBenchmark public void testAtomicInteger() atomicincrementAndGet()

GenerateMicroBenchmark public void testReentrantLock() locklock() primCounter++ lockunlock()

GenerateMicroBenchmark public void testIntrinsicLock() synchronized (intrinsicLock) primCounter++

38 copy JavaTechDays 2011 Oracle Corporation

Concurrencyатомарный счётчик

0 16 32 48 64 80 96 112 128

1000

10000

100000

Atomic Counter Performance

Intrinsic AtomicInteger ReentrantLock

Threads

ops

sec

8x8 CPUs Solaris 6u25

39 copy JavaTechDays 2011 Oracle Corporation

ConcurrencyReentrantLock vs synchronized

bull Семантика одинаковаndash Требования к видимости памяти

ndash Рекурсивный

bull Плюсы jucRLndash Очередь потоков держится на стороне JVM

bull опционально FIFO-политика при захвате-освобождении

bull позволяет быть ldquoчестнымrdquo на любой платформе

ndash Barging FIFO policy

bull lock() может быть сразу удовлетворён даже если в очереди есть потоки

bull сильно улучшает производительность при конфликте блокировок

ndash Допускается несколько Condition

bull Минусы jucRLndash Нет scopeов требуется ручной unlock() через finally

bull Должно быть проще с ARM в JDK7

40 copy JavaTechDays 2011 Oracle Corporation

Concurrencyбесконфликтный захват

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

10000

20000

30000

40000

50000

60000

70000

80000

90000

100000

110000

120000

130000

140000

150000

Uncontended Lock Performance

intrinsic jucReentrantL (non-fair) jucReentrantL (fair)

Threads

op

sse

c

41 copy JavaTechDays 2011 Oracle Corporation

Concurrencyконфликтный захват

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

500

1000

1500

2000

2500

3000

3500

4000

4500

Contended Lock Performance

intrinsic jucReentrantL (non-fair) jucReentrantL (fair)

Threads

op

sse

c

43 copy 2011 JavaTechDays Oracle Corporation

bull hellip естьbull hellip работаетbull hellip работает хорошоbull hellip знает о железе всё

ndash Количество и тип CPUndash Поддерживаемые инcтрукции (SSEx AVX VIS)ndash Топологию памяти (в тч размеры кэшей и их характеристики)

bull hellip знает о приложении много всегоndash Иерархию загруженных классовndash Актуальную статистику создания объектовndash Горячий кодndash Какие ветвления исполнялисьndash Какие значения использовалисьndash Многое другое

bull hellip не боится использовать эти знания для компиляции

JITфакты

44 copy 2011 JavaTechDays Oracle Corporation

JITоптимизации

46 copy 2011 JavaTechDays Oracle Corporation

JITкак писать код

bull Используйте стандартные библиотекиndash Зачем писать собственный стандартный контейнер

bull Используйте высокоуровневый API ndash javautilndash javautilconcurrentndash NIO NIO2ndash вообще библиотеки

bull Код должен правильным и понятнымndash Сначала правильноndash Потом алгоритмически ldquoбыстроrdquondash Код не должен быть JIT-oriented

bull Правильно используйте возможности языкаndash EPIC FAIL штатная передача управления exceptionамиndash FAIL Возврат ldquoисключенияrdquo через return ltкод_ошибкиgtndash FAIL int вместо Enum или boolean

47 copy 2011 JavaTechDays Oracle Corporation

Как получить ассемблерный код метода

ndash Обычным дебаггером )

ndash JVMTI

ndash -XX+PrintAssemblybull httpwikissuncomdisplayHotSpotInternalsPrintAssembly

JITдля любопытных

54 copy JavaTechDays 2011 Oracle Corporation

StartupEclipse

bull Типичная конфигурацияndash 2x2 Intel i5 26 Ghz Ubuntu 1010 i686 JDK 6u25ndash Eclipse JDT (Galileo)

bull Типичные метрикиndash 6000 загруженных классовndash 1000 методов скомпилированоndash 512 Mb зарезервированного пространства в кучеndash 25 Mb кучи использовано после стартапа

bull Известные ldquoпроблемыrdquondash Загрузка и верификация классовndash JIT-компиляция

55 copy JavaTechDays 2011 Oracle Corporation

StartupEclipse

bull Метрика секунд на запуск-завершениеndash Файловые кеши прогреты практически нулевой дисковый IO

default CDS CDS + no-verify

абсолютное время

583 [574 592]

481[473 484]

461[456 474]

загрузка классов

501[491 511]

339[312 366]

301[294 308]

компиляция 051[043 059]

051[044 058]

051[042 060]

56 copy JavaTechDays 2011 Oracle Corporation

Startupдлинные приложения

bull Важно только для коротких приложенийndash Чем дольше работает приложение тем меньше удельные затраты на

загрузку классов и компиляцию

bull Пример 8 часа работает IntelliJ IDEA 10xndash 26600 классов загруженоndash 5315 методов скомпилировано

bull Загрузка классовndash Всего потрачено 202 с ~07 общего времениndash 10 мсек на класс

bull Компиляцияndash Всего потрачено 112 с ~003 общего времениndash 20 мсек на метод

57 copy JavaTechDays 2011 Oracle Corporation

Whats Next

bull Послушать ещёndash JavaOne Moscow (апрель 2011)

bull Проблема со слайдамиndash Найдите нас на конференцииndash Напишите нам письмо

bull Проблема с JDKndash httpopenjdkjavanetndash Задайте вопрос в OpenJDKndash а лучше сделайте патч и дайте его в OpenJDK на review

58 copy JavaTechDays 2011 Oracle Corporation

QA

Page 29: Java Platform Performance BoF - Aleksey Shipilëv · – 2x2 Intel i5 2.6 Ghz, Ubuntu 10.10 i686, JDK 6u25 • Три варианта эксперимента: – 1 экземпляр

36 copy JavaTechDays 2011 Oracle Corporation

ConcurrencyjavautilconcurrentLock

bull Построены на базе jucAbstractQueueSynchronizerndash Использует атомики

bull CAS

ndash Использует Unsafepark()unpark()

bull интринзики для cond_wait()cond_signal()WaitForSingleObject()

bull ReentrantLockndash По семантике эквивалентен synchronized

bull Рекурсивный захват проверка на threadID

bull Ставит потоки во внутреннюю очередь и делает park()

ndash Non-Fair (default)

bull Не гарантирует отсутствие starvation

bull Barging FIFO (CAS)

bull Лучшая производительность

ndash Fair

bull Гарантирует отсутствие starvation

bull FIFO

bull Честность в обмен на производительностьhttpgeecsoswegoedudlpapersaqspdf

37 copy JavaTechDays 2011 Oracle Corporation

Concurrencyатомарный счётчик

private AtomicInteger atomic = new AtomicInteger() private ReentrantLock lock = new ReentrantLock() private final Object intrinsicLock = new Object() private int primCounter = 0

GenerateMicroBenchmark public void testAtomicInteger() atomicincrementAndGet()

GenerateMicroBenchmark public void testReentrantLock() locklock() primCounter++ lockunlock()

GenerateMicroBenchmark public void testIntrinsicLock() synchronized (intrinsicLock) primCounter++

38 copy JavaTechDays 2011 Oracle Corporation

Concurrencyатомарный счётчик

0 16 32 48 64 80 96 112 128

1000

10000

100000

Atomic Counter Performance

Intrinsic AtomicInteger ReentrantLock

Threads

ops

sec

8x8 CPUs Solaris 6u25

39 copy JavaTechDays 2011 Oracle Corporation

ConcurrencyReentrantLock vs synchronized

bull Семантика одинаковаndash Требования к видимости памяти

ndash Рекурсивный

bull Плюсы jucRLndash Очередь потоков держится на стороне JVM

bull опционально FIFO-политика при захвате-освобождении

bull позволяет быть ldquoчестнымrdquo на любой платформе

ndash Barging FIFO policy

bull lock() может быть сразу удовлетворён даже если в очереди есть потоки

bull сильно улучшает производительность при конфликте блокировок

ndash Допускается несколько Condition

bull Минусы jucRLndash Нет scopeов требуется ручной unlock() через finally

bull Должно быть проще с ARM в JDK7

40 copy JavaTechDays 2011 Oracle Corporation

Concurrencyбесконфликтный захват

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

10000

20000

30000

40000

50000

60000

70000

80000

90000

100000

110000

120000

130000

140000

150000

Uncontended Lock Performance

intrinsic jucReentrantL (non-fair) jucReentrantL (fair)

Threads

op

sse

c

41 copy JavaTechDays 2011 Oracle Corporation

Concurrencyконфликтный захват

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

500

1000

1500

2000

2500

3000

3500

4000

4500

Contended Lock Performance

intrinsic jucReentrantL (non-fair) jucReentrantL (fair)

Threads

op

sse

c

43 copy 2011 JavaTechDays Oracle Corporation

bull hellip естьbull hellip работаетbull hellip работает хорошоbull hellip знает о железе всё

ndash Количество и тип CPUndash Поддерживаемые инcтрукции (SSEx AVX VIS)ndash Топологию памяти (в тч размеры кэшей и их характеристики)

bull hellip знает о приложении много всегоndash Иерархию загруженных классовndash Актуальную статистику создания объектовndash Горячий кодndash Какие ветвления исполнялисьndash Какие значения использовалисьndash Многое другое

bull hellip не боится использовать эти знания для компиляции

JITфакты

44 copy 2011 JavaTechDays Oracle Corporation

JITоптимизации

46 copy 2011 JavaTechDays Oracle Corporation

JITкак писать код

bull Используйте стандартные библиотекиndash Зачем писать собственный стандартный контейнер

bull Используйте высокоуровневый API ndash javautilndash javautilconcurrentndash NIO NIO2ndash вообще библиотеки

bull Код должен правильным и понятнымndash Сначала правильноndash Потом алгоритмически ldquoбыстроrdquondash Код не должен быть JIT-oriented

bull Правильно используйте возможности языкаndash EPIC FAIL штатная передача управления exceptionамиndash FAIL Возврат ldquoисключенияrdquo через return ltкод_ошибкиgtndash FAIL int вместо Enum или boolean

47 copy 2011 JavaTechDays Oracle Corporation

Как получить ассемблерный код метода

ndash Обычным дебаггером )

ndash JVMTI

ndash -XX+PrintAssemblybull httpwikissuncomdisplayHotSpotInternalsPrintAssembly

JITдля любопытных

54 copy JavaTechDays 2011 Oracle Corporation

StartupEclipse

bull Типичная конфигурацияndash 2x2 Intel i5 26 Ghz Ubuntu 1010 i686 JDK 6u25ndash Eclipse JDT (Galileo)

bull Типичные метрикиndash 6000 загруженных классовndash 1000 методов скомпилированоndash 512 Mb зарезервированного пространства в кучеndash 25 Mb кучи использовано после стартапа

bull Известные ldquoпроблемыrdquondash Загрузка и верификация классовndash JIT-компиляция

55 copy JavaTechDays 2011 Oracle Corporation

StartupEclipse

bull Метрика секунд на запуск-завершениеndash Файловые кеши прогреты практически нулевой дисковый IO

default CDS CDS + no-verify

абсолютное время

583 [574 592]

481[473 484]

461[456 474]

загрузка классов

501[491 511]

339[312 366]

301[294 308]

компиляция 051[043 059]

051[044 058]

051[042 060]

56 copy JavaTechDays 2011 Oracle Corporation

Startupдлинные приложения

bull Важно только для коротких приложенийndash Чем дольше работает приложение тем меньше удельные затраты на

загрузку классов и компиляцию

bull Пример 8 часа работает IntelliJ IDEA 10xndash 26600 классов загруженоndash 5315 методов скомпилировано

bull Загрузка классовndash Всего потрачено 202 с ~07 общего времениndash 10 мсек на класс

bull Компиляцияndash Всего потрачено 112 с ~003 общего времениndash 20 мсек на метод

57 copy JavaTechDays 2011 Oracle Corporation

Whats Next

bull Послушать ещёndash JavaOne Moscow (апрель 2011)

bull Проблема со слайдамиndash Найдите нас на конференцииndash Напишите нам письмо

bull Проблема с JDKndash httpopenjdkjavanetndash Задайте вопрос в OpenJDKndash а лучше сделайте патч и дайте его в OpenJDK на review

58 copy JavaTechDays 2011 Oracle Corporation

QA

Page 30: Java Platform Performance BoF - Aleksey Shipilëv · – 2x2 Intel i5 2.6 Ghz, Ubuntu 10.10 i686, JDK 6u25 • Три варианта эксперимента: – 1 экземпляр

37 copy JavaTechDays 2011 Oracle Corporation

Concurrencyатомарный счётчик

private AtomicInteger atomic = new AtomicInteger() private ReentrantLock lock = new ReentrantLock() private final Object intrinsicLock = new Object() private int primCounter = 0

GenerateMicroBenchmark public void testAtomicInteger() atomicincrementAndGet()

GenerateMicroBenchmark public void testReentrantLock() locklock() primCounter++ lockunlock()

GenerateMicroBenchmark public void testIntrinsicLock() synchronized (intrinsicLock) primCounter++

38 copy JavaTechDays 2011 Oracle Corporation

Concurrencyатомарный счётчик

0 16 32 48 64 80 96 112 128

1000

10000

100000

Atomic Counter Performance

Intrinsic AtomicInteger ReentrantLock

Threads

ops

sec

8x8 CPUs Solaris 6u25

39 copy JavaTechDays 2011 Oracle Corporation

ConcurrencyReentrantLock vs synchronized

bull Семантика одинаковаndash Требования к видимости памяти

ndash Рекурсивный

bull Плюсы jucRLndash Очередь потоков держится на стороне JVM

bull опционально FIFO-политика при захвате-освобождении

bull позволяет быть ldquoчестнымrdquo на любой платформе

ndash Barging FIFO policy

bull lock() может быть сразу удовлетворён даже если в очереди есть потоки

bull сильно улучшает производительность при конфликте блокировок

ndash Допускается несколько Condition

bull Минусы jucRLndash Нет scopeов требуется ручной unlock() через finally

bull Должно быть проще с ARM в JDK7

40 copy JavaTechDays 2011 Oracle Corporation

Concurrencyбесконфликтный захват

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

10000

20000

30000

40000

50000

60000

70000

80000

90000

100000

110000

120000

130000

140000

150000

Uncontended Lock Performance

intrinsic jucReentrantL (non-fair) jucReentrantL (fair)

Threads

op

sse

c

41 copy JavaTechDays 2011 Oracle Corporation

Concurrencyконфликтный захват

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

500

1000

1500

2000

2500

3000

3500

4000

4500

Contended Lock Performance

intrinsic jucReentrantL (non-fair) jucReentrantL (fair)

Threads

op

sse

c

43 copy 2011 JavaTechDays Oracle Corporation

bull hellip естьbull hellip работаетbull hellip работает хорошоbull hellip знает о железе всё

ndash Количество и тип CPUndash Поддерживаемые инcтрукции (SSEx AVX VIS)ndash Топологию памяти (в тч размеры кэшей и их характеристики)

bull hellip знает о приложении много всегоndash Иерархию загруженных классовndash Актуальную статистику создания объектовndash Горячий кодndash Какие ветвления исполнялисьndash Какие значения использовалисьndash Многое другое

bull hellip не боится использовать эти знания для компиляции

JITфакты

44 copy 2011 JavaTechDays Oracle Corporation

JITоптимизации

46 copy 2011 JavaTechDays Oracle Corporation

JITкак писать код

bull Используйте стандартные библиотекиndash Зачем писать собственный стандартный контейнер

bull Используйте высокоуровневый API ndash javautilndash javautilconcurrentndash NIO NIO2ndash вообще библиотеки

bull Код должен правильным и понятнымndash Сначала правильноndash Потом алгоритмически ldquoбыстроrdquondash Код не должен быть JIT-oriented

bull Правильно используйте возможности языкаndash EPIC FAIL штатная передача управления exceptionамиndash FAIL Возврат ldquoисключенияrdquo через return ltкод_ошибкиgtndash FAIL int вместо Enum или boolean

47 copy 2011 JavaTechDays Oracle Corporation

Как получить ассемблерный код метода

ndash Обычным дебаггером )

ndash JVMTI

ndash -XX+PrintAssemblybull httpwikissuncomdisplayHotSpotInternalsPrintAssembly

JITдля любопытных

54 copy JavaTechDays 2011 Oracle Corporation

StartupEclipse

bull Типичная конфигурацияndash 2x2 Intel i5 26 Ghz Ubuntu 1010 i686 JDK 6u25ndash Eclipse JDT (Galileo)

bull Типичные метрикиndash 6000 загруженных классовndash 1000 методов скомпилированоndash 512 Mb зарезервированного пространства в кучеndash 25 Mb кучи использовано после стартапа

bull Известные ldquoпроблемыrdquondash Загрузка и верификация классовndash JIT-компиляция

55 copy JavaTechDays 2011 Oracle Corporation

StartupEclipse

bull Метрика секунд на запуск-завершениеndash Файловые кеши прогреты практически нулевой дисковый IO

default CDS CDS + no-verify

абсолютное время

583 [574 592]

481[473 484]

461[456 474]

загрузка классов

501[491 511]

339[312 366]

301[294 308]

компиляция 051[043 059]

051[044 058]

051[042 060]

56 copy JavaTechDays 2011 Oracle Corporation

Startupдлинные приложения

bull Важно только для коротких приложенийndash Чем дольше работает приложение тем меньше удельные затраты на

загрузку классов и компиляцию

bull Пример 8 часа работает IntelliJ IDEA 10xndash 26600 классов загруженоndash 5315 методов скомпилировано

bull Загрузка классовndash Всего потрачено 202 с ~07 общего времениndash 10 мсек на класс

bull Компиляцияndash Всего потрачено 112 с ~003 общего времениndash 20 мсек на метод

57 copy JavaTechDays 2011 Oracle Corporation

Whats Next

bull Послушать ещёndash JavaOne Moscow (апрель 2011)

bull Проблема со слайдамиndash Найдите нас на конференцииndash Напишите нам письмо

bull Проблема с JDKndash httpopenjdkjavanetndash Задайте вопрос в OpenJDKndash а лучше сделайте патч и дайте его в OpenJDK на review

58 copy JavaTechDays 2011 Oracle Corporation

QA

Page 31: Java Platform Performance BoF - Aleksey Shipilëv · – 2x2 Intel i5 2.6 Ghz, Ubuntu 10.10 i686, JDK 6u25 • Три варианта эксперимента: – 1 экземпляр

38 copy JavaTechDays 2011 Oracle Corporation

Concurrencyатомарный счётчик

0 16 32 48 64 80 96 112 128

1000

10000

100000

Atomic Counter Performance

Intrinsic AtomicInteger ReentrantLock

Threads

ops

sec

8x8 CPUs Solaris 6u25

39 copy JavaTechDays 2011 Oracle Corporation

ConcurrencyReentrantLock vs synchronized

bull Семантика одинаковаndash Требования к видимости памяти

ndash Рекурсивный

bull Плюсы jucRLndash Очередь потоков держится на стороне JVM

bull опционально FIFO-политика при захвате-освобождении

bull позволяет быть ldquoчестнымrdquo на любой платформе

ndash Barging FIFO policy

bull lock() может быть сразу удовлетворён даже если в очереди есть потоки

bull сильно улучшает производительность при конфликте блокировок

ndash Допускается несколько Condition

bull Минусы jucRLndash Нет scopeов требуется ручной unlock() через finally

bull Должно быть проще с ARM в JDK7

40 copy JavaTechDays 2011 Oracle Corporation

Concurrencyбесконфликтный захват

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

10000

20000

30000

40000

50000

60000

70000

80000

90000

100000

110000

120000

130000

140000

150000

Uncontended Lock Performance

intrinsic jucReentrantL (non-fair) jucReentrantL (fair)

Threads

op

sse

c

41 copy JavaTechDays 2011 Oracle Corporation

Concurrencyконфликтный захват

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

500

1000

1500

2000

2500

3000

3500

4000

4500

Contended Lock Performance

intrinsic jucReentrantL (non-fair) jucReentrantL (fair)

Threads

op

sse

c

43 copy 2011 JavaTechDays Oracle Corporation

bull hellip естьbull hellip работаетbull hellip работает хорошоbull hellip знает о железе всё

ndash Количество и тип CPUndash Поддерживаемые инcтрукции (SSEx AVX VIS)ndash Топологию памяти (в тч размеры кэшей и их характеристики)

bull hellip знает о приложении много всегоndash Иерархию загруженных классовndash Актуальную статистику создания объектовndash Горячий кодndash Какие ветвления исполнялисьndash Какие значения использовалисьndash Многое другое

bull hellip не боится использовать эти знания для компиляции

JITфакты

44 copy 2011 JavaTechDays Oracle Corporation

JITоптимизации

46 copy 2011 JavaTechDays Oracle Corporation

JITкак писать код

bull Используйте стандартные библиотекиndash Зачем писать собственный стандартный контейнер

bull Используйте высокоуровневый API ndash javautilndash javautilconcurrentndash NIO NIO2ndash вообще библиотеки

bull Код должен правильным и понятнымndash Сначала правильноndash Потом алгоритмически ldquoбыстроrdquondash Код не должен быть JIT-oriented

bull Правильно используйте возможности языкаndash EPIC FAIL штатная передача управления exceptionамиndash FAIL Возврат ldquoисключенияrdquo через return ltкод_ошибкиgtndash FAIL int вместо Enum или boolean

47 copy 2011 JavaTechDays Oracle Corporation

Как получить ассемблерный код метода

ndash Обычным дебаггером )

ndash JVMTI

ndash -XX+PrintAssemblybull httpwikissuncomdisplayHotSpotInternalsPrintAssembly

JITдля любопытных

54 copy JavaTechDays 2011 Oracle Corporation

StartupEclipse

bull Типичная конфигурацияndash 2x2 Intel i5 26 Ghz Ubuntu 1010 i686 JDK 6u25ndash Eclipse JDT (Galileo)

bull Типичные метрикиndash 6000 загруженных классовndash 1000 методов скомпилированоndash 512 Mb зарезервированного пространства в кучеndash 25 Mb кучи использовано после стартапа

bull Известные ldquoпроблемыrdquondash Загрузка и верификация классовndash JIT-компиляция

55 copy JavaTechDays 2011 Oracle Corporation

StartupEclipse

bull Метрика секунд на запуск-завершениеndash Файловые кеши прогреты практически нулевой дисковый IO

default CDS CDS + no-verify

абсолютное время

583 [574 592]

481[473 484]

461[456 474]

загрузка классов

501[491 511]

339[312 366]

301[294 308]

компиляция 051[043 059]

051[044 058]

051[042 060]

56 copy JavaTechDays 2011 Oracle Corporation

Startupдлинные приложения

bull Важно только для коротких приложенийndash Чем дольше работает приложение тем меньше удельные затраты на

загрузку классов и компиляцию

bull Пример 8 часа работает IntelliJ IDEA 10xndash 26600 классов загруженоndash 5315 методов скомпилировано

bull Загрузка классовndash Всего потрачено 202 с ~07 общего времениndash 10 мсек на класс

bull Компиляцияndash Всего потрачено 112 с ~003 общего времениndash 20 мсек на метод

57 copy JavaTechDays 2011 Oracle Corporation

Whats Next

bull Послушать ещёndash JavaOne Moscow (апрель 2011)

bull Проблема со слайдамиndash Найдите нас на конференцииndash Напишите нам письмо

bull Проблема с JDKndash httpopenjdkjavanetndash Задайте вопрос в OpenJDKndash а лучше сделайте патч и дайте его в OpenJDK на review

58 copy JavaTechDays 2011 Oracle Corporation

QA

Page 32: Java Platform Performance BoF - Aleksey Shipilëv · – 2x2 Intel i5 2.6 Ghz, Ubuntu 10.10 i686, JDK 6u25 • Три варианта эксперимента: – 1 экземпляр

39 copy JavaTechDays 2011 Oracle Corporation

ConcurrencyReentrantLock vs synchronized

bull Семантика одинаковаndash Требования к видимости памяти

ndash Рекурсивный

bull Плюсы jucRLndash Очередь потоков держится на стороне JVM

bull опционально FIFO-политика при захвате-освобождении

bull позволяет быть ldquoчестнымrdquo на любой платформе

ndash Barging FIFO policy

bull lock() может быть сразу удовлетворён даже если в очереди есть потоки

bull сильно улучшает производительность при конфликте блокировок

ndash Допускается несколько Condition

bull Минусы jucRLndash Нет scopeов требуется ручной unlock() через finally

bull Должно быть проще с ARM в JDK7

40 copy JavaTechDays 2011 Oracle Corporation

Concurrencyбесконфликтный захват

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

10000

20000

30000

40000

50000

60000

70000

80000

90000

100000

110000

120000

130000

140000

150000

Uncontended Lock Performance

intrinsic jucReentrantL (non-fair) jucReentrantL (fair)

Threads

op

sse

c

41 copy JavaTechDays 2011 Oracle Corporation

Concurrencyконфликтный захват

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

500

1000

1500

2000

2500

3000

3500

4000

4500

Contended Lock Performance

intrinsic jucReentrantL (non-fair) jucReentrantL (fair)

Threads

op

sse

c

43 copy 2011 JavaTechDays Oracle Corporation

bull hellip естьbull hellip работаетbull hellip работает хорошоbull hellip знает о железе всё

ndash Количество и тип CPUndash Поддерживаемые инcтрукции (SSEx AVX VIS)ndash Топологию памяти (в тч размеры кэшей и их характеристики)

bull hellip знает о приложении много всегоndash Иерархию загруженных классовndash Актуальную статистику создания объектовndash Горячий кодndash Какие ветвления исполнялисьndash Какие значения использовалисьndash Многое другое

bull hellip не боится использовать эти знания для компиляции

JITфакты

44 copy 2011 JavaTechDays Oracle Corporation

JITоптимизации

46 copy 2011 JavaTechDays Oracle Corporation

JITкак писать код

bull Используйте стандартные библиотекиndash Зачем писать собственный стандартный контейнер

bull Используйте высокоуровневый API ndash javautilndash javautilconcurrentndash NIO NIO2ndash вообще библиотеки

bull Код должен правильным и понятнымndash Сначала правильноndash Потом алгоритмически ldquoбыстроrdquondash Код не должен быть JIT-oriented

bull Правильно используйте возможности языкаndash EPIC FAIL штатная передача управления exceptionамиndash FAIL Возврат ldquoисключенияrdquo через return ltкод_ошибкиgtndash FAIL int вместо Enum или boolean

47 copy 2011 JavaTechDays Oracle Corporation

Как получить ассемблерный код метода

ndash Обычным дебаггером )

ndash JVMTI

ndash -XX+PrintAssemblybull httpwikissuncomdisplayHotSpotInternalsPrintAssembly

JITдля любопытных

54 copy JavaTechDays 2011 Oracle Corporation

StartupEclipse

bull Типичная конфигурацияndash 2x2 Intel i5 26 Ghz Ubuntu 1010 i686 JDK 6u25ndash Eclipse JDT (Galileo)

bull Типичные метрикиndash 6000 загруженных классовndash 1000 методов скомпилированоndash 512 Mb зарезервированного пространства в кучеndash 25 Mb кучи использовано после стартапа

bull Известные ldquoпроблемыrdquondash Загрузка и верификация классовndash JIT-компиляция

55 copy JavaTechDays 2011 Oracle Corporation

StartupEclipse

bull Метрика секунд на запуск-завершениеndash Файловые кеши прогреты практически нулевой дисковый IO

default CDS CDS + no-verify

абсолютное время

583 [574 592]

481[473 484]

461[456 474]

загрузка классов

501[491 511]

339[312 366]

301[294 308]

компиляция 051[043 059]

051[044 058]

051[042 060]

56 copy JavaTechDays 2011 Oracle Corporation

Startupдлинные приложения

bull Важно только для коротких приложенийndash Чем дольше работает приложение тем меньше удельные затраты на

загрузку классов и компиляцию

bull Пример 8 часа работает IntelliJ IDEA 10xndash 26600 классов загруженоndash 5315 методов скомпилировано

bull Загрузка классовndash Всего потрачено 202 с ~07 общего времениndash 10 мсек на класс

bull Компиляцияndash Всего потрачено 112 с ~003 общего времениndash 20 мсек на метод

57 copy JavaTechDays 2011 Oracle Corporation

Whats Next

bull Послушать ещёndash JavaOne Moscow (апрель 2011)

bull Проблема со слайдамиndash Найдите нас на конференцииndash Напишите нам письмо

bull Проблема с JDKndash httpopenjdkjavanetndash Задайте вопрос в OpenJDKndash а лучше сделайте патч и дайте его в OpenJDK на review

58 copy JavaTechDays 2011 Oracle Corporation

QA

Page 33: Java Platform Performance BoF - Aleksey Shipilëv · – 2x2 Intel i5 2.6 Ghz, Ubuntu 10.10 i686, JDK 6u25 • Три варианта эксперимента: – 1 экземпляр

40 copy JavaTechDays 2011 Oracle Corporation

Concurrencyбесконфликтный захват

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

10000

20000

30000

40000

50000

60000

70000

80000

90000

100000

110000

120000

130000

140000

150000

Uncontended Lock Performance

intrinsic jucReentrantL (non-fair) jucReentrantL (fair)

Threads

op

sse

c

41 copy JavaTechDays 2011 Oracle Corporation

Concurrencyконфликтный захват

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

500

1000

1500

2000

2500

3000

3500

4000

4500

Contended Lock Performance

intrinsic jucReentrantL (non-fair) jucReentrantL (fair)

Threads

op

sse

c

43 copy 2011 JavaTechDays Oracle Corporation

bull hellip естьbull hellip работаетbull hellip работает хорошоbull hellip знает о железе всё

ndash Количество и тип CPUndash Поддерживаемые инcтрукции (SSEx AVX VIS)ndash Топологию памяти (в тч размеры кэшей и их характеристики)

bull hellip знает о приложении много всегоndash Иерархию загруженных классовndash Актуальную статистику создания объектовndash Горячий кодndash Какие ветвления исполнялисьndash Какие значения использовалисьndash Многое другое

bull hellip не боится использовать эти знания для компиляции

JITфакты

44 copy 2011 JavaTechDays Oracle Corporation

JITоптимизации

46 copy 2011 JavaTechDays Oracle Corporation

JITкак писать код

bull Используйте стандартные библиотекиndash Зачем писать собственный стандартный контейнер

bull Используйте высокоуровневый API ndash javautilndash javautilconcurrentndash NIO NIO2ndash вообще библиотеки

bull Код должен правильным и понятнымndash Сначала правильноndash Потом алгоритмически ldquoбыстроrdquondash Код не должен быть JIT-oriented

bull Правильно используйте возможности языкаndash EPIC FAIL штатная передача управления exceptionамиndash FAIL Возврат ldquoисключенияrdquo через return ltкод_ошибкиgtndash FAIL int вместо Enum или boolean

47 copy 2011 JavaTechDays Oracle Corporation

Как получить ассемблерный код метода

ndash Обычным дебаггером )

ndash JVMTI

ndash -XX+PrintAssemblybull httpwikissuncomdisplayHotSpotInternalsPrintAssembly

JITдля любопытных

54 copy JavaTechDays 2011 Oracle Corporation

StartupEclipse

bull Типичная конфигурацияndash 2x2 Intel i5 26 Ghz Ubuntu 1010 i686 JDK 6u25ndash Eclipse JDT (Galileo)

bull Типичные метрикиndash 6000 загруженных классовndash 1000 методов скомпилированоndash 512 Mb зарезервированного пространства в кучеndash 25 Mb кучи использовано после стартапа

bull Известные ldquoпроблемыrdquondash Загрузка и верификация классовndash JIT-компиляция

55 copy JavaTechDays 2011 Oracle Corporation

StartupEclipse

bull Метрика секунд на запуск-завершениеndash Файловые кеши прогреты практически нулевой дисковый IO

default CDS CDS + no-verify

абсолютное время

583 [574 592]

481[473 484]

461[456 474]

загрузка классов

501[491 511]

339[312 366]

301[294 308]

компиляция 051[043 059]

051[044 058]

051[042 060]

56 copy JavaTechDays 2011 Oracle Corporation

Startupдлинные приложения

bull Важно только для коротких приложенийndash Чем дольше работает приложение тем меньше удельные затраты на

загрузку классов и компиляцию

bull Пример 8 часа работает IntelliJ IDEA 10xndash 26600 классов загруженоndash 5315 методов скомпилировано

bull Загрузка классовndash Всего потрачено 202 с ~07 общего времениndash 10 мсек на класс

bull Компиляцияndash Всего потрачено 112 с ~003 общего времениndash 20 мсек на метод

57 copy JavaTechDays 2011 Oracle Corporation

Whats Next

bull Послушать ещёndash JavaOne Moscow (апрель 2011)

bull Проблема со слайдамиndash Найдите нас на конференцииndash Напишите нам письмо

bull Проблема с JDKndash httpopenjdkjavanetndash Задайте вопрос в OpenJDKndash а лучше сделайте патч и дайте его в OpenJDK на review

58 copy JavaTechDays 2011 Oracle Corporation

QA

Page 34: Java Platform Performance BoF - Aleksey Shipilëv · – 2x2 Intel i5 2.6 Ghz, Ubuntu 10.10 i686, JDK 6u25 • Три варианта эксперимента: – 1 экземпляр

41 copy JavaTechDays 2011 Oracle Corporation

Concurrencyконфликтный захват

8x8 CPUs Solaris 6u25

0 16 32 48 64 80 96 112 128

0

500

1000

1500

2000

2500

3000

3500

4000

4500

Contended Lock Performance

intrinsic jucReentrantL (non-fair) jucReentrantL (fair)

Threads

op

sse

c

43 copy 2011 JavaTechDays Oracle Corporation

bull hellip естьbull hellip работаетbull hellip работает хорошоbull hellip знает о железе всё

ndash Количество и тип CPUndash Поддерживаемые инcтрукции (SSEx AVX VIS)ndash Топологию памяти (в тч размеры кэшей и их характеристики)

bull hellip знает о приложении много всегоndash Иерархию загруженных классовndash Актуальную статистику создания объектовndash Горячий кодndash Какие ветвления исполнялисьndash Какие значения использовалисьndash Многое другое

bull hellip не боится использовать эти знания для компиляции

JITфакты

44 copy 2011 JavaTechDays Oracle Corporation

JITоптимизации

46 copy 2011 JavaTechDays Oracle Corporation

JITкак писать код

bull Используйте стандартные библиотекиndash Зачем писать собственный стандартный контейнер

bull Используйте высокоуровневый API ndash javautilndash javautilconcurrentndash NIO NIO2ndash вообще библиотеки

bull Код должен правильным и понятнымndash Сначала правильноndash Потом алгоритмически ldquoбыстроrdquondash Код не должен быть JIT-oriented

bull Правильно используйте возможности языкаndash EPIC FAIL штатная передача управления exceptionамиndash FAIL Возврат ldquoисключенияrdquo через return ltкод_ошибкиgtndash FAIL int вместо Enum или boolean

47 copy 2011 JavaTechDays Oracle Corporation

Как получить ассемблерный код метода

ndash Обычным дебаггером )

ndash JVMTI

ndash -XX+PrintAssemblybull httpwikissuncomdisplayHotSpotInternalsPrintAssembly

JITдля любопытных

54 copy JavaTechDays 2011 Oracle Corporation

StartupEclipse

bull Типичная конфигурацияndash 2x2 Intel i5 26 Ghz Ubuntu 1010 i686 JDK 6u25ndash Eclipse JDT (Galileo)

bull Типичные метрикиndash 6000 загруженных классовndash 1000 методов скомпилированоndash 512 Mb зарезервированного пространства в кучеndash 25 Mb кучи использовано после стартапа

bull Известные ldquoпроблемыrdquondash Загрузка и верификация классовndash JIT-компиляция

55 copy JavaTechDays 2011 Oracle Corporation

StartupEclipse

bull Метрика секунд на запуск-завершениеndash Файловые кеши прогреты практически нулевой дисковый IO

default CDS CDS + no-verify

абсолютное время

583 [574 592]

481[473 484]

461[456 474]

загрузка классов

501[491 511]

339[312 366]

301[294 308]

компиляция 051[043 059]

051[044 058]

051[042 060]

56 copy JavaTechDays 2011 Oracle Corporation

Startupдлинные приложения

bull Важно только для коротких приложенийndash Чем дольше работает приложение тем меньше удельные затраты на

загрузку классов и компиляцию

bull Пример 8 часа работает IntelliJ IDEA 10xndash 26600 классов загруженоndash 5315 методов скомпилировано

bull Загрузка классовndash Всего потрачено 202 с ~07 общего времениndash 10 мсек на класс

bull Компиляцияndash Всего потрачено 112 с ~003 общего времениndash 20 мсек на метод

57 copy JavaTechDays 2011 Oracle Corporation

Whats Next

bull Послушать ещёndash JavaOne Moscow (апрель 2011)

bull Проблема со слайдамиndash Найдите нас на конференцииndash Напишите нам письмо

bull Проблема с JDKndash httpopenjdkjavanetndash Задайте вопрос в OpenJDKndash а лучше сделайте патч и дайте его в OpenJDK на review

58 copy JavaTechDays 2011 Oracle Corporation

QA

Page 35: Java Platform Performance BoF - Aleksey Shipilëv · – 2x2 Intel i5 2.6 Ghz, Ubuntu 10.10 i686, JDK 6u25 • Три варианта эксперимента: – 1 экземпляр

43 copy 2011 JavaTechDays Oracle Corporation

bull hellip естьbull hellip работаетbull hellip работает хорошоbull hellip знает о железе всё

ndash Количество и тип CPUndash Поддерживаемые инcтрукции (SSEx AVX VIS)ndash Топологию памяти (в тч размеры кэшей и их характеристики)

bull hellip знает о приложении много всегоndash Иерархию загруженных классовndash Актуальную статистику создания объектовndash Горячий кодndash Какие ветвления исполнялисьndash Какие значения использовалисьndash Многое другое

bull hellip не боится использовать эти знания для компиляции

JITфакты

44 copy 2011 JavaTechDays Oracle Corporation

JITоптимизации

46 copy 2011 JavaTechDays Oracle Corporation

JITкак писать код

bull Используйте стандартные библиотекиndash Зачем писать собственный стандартный контейнер

bull Используйте высокоуровневый API ndash javautilndash javautilconcurrentndash NIO NIO2ndash вообще библиотеки

bull Код должен правильным и понятнымndash Сначала правильноndash Потом алгоритмически ldquoбыстроrdquondash Код не должен быть JIT-oriented

bull Правильно используйте возможности языкаndash EPIC FAIL штатная передача управления exceptionамиndash FAIL Возврат ldquoисключенияrdquo через return ltкод_ошибкиgtndash FAIL int вместо Enum или boolean

47 copy 2011 JavaTechDays Oracle Corporation

Как получить ассемблерный код метода

ndash Обычным дебаггером )

ndash JVMTI

ndash -XX+PrintAssemblybull httpwikissuncomdisplayHotSpotInternalsPrintAssembly

JITдля любопытных

54 copy JavaTechDays 2011 Oracle Corporation

StartupEclipse

bull Типичная конфигурацияndash 2x2 Intel i5 26 Ghz Ubuntu 1010 i686 JDK 6u25ndash Eclipse JDT (Galileo)

bull Типичные метрикиndash 6000 загруженных классовndash 1000 методов скомпилированоndash 512 Mb зарезервированного пространства в кучеndash 25 Mb кучи использовано после стартапа

bull Известные ldquoпроблемыrdquondash Загрузка и верификация классовndash JIT-компиляция

55 copy JavaTechDays 2011 Oracle Corporation

StartupEclipse

bull Метрика секунд на запуск-завершениеndash Файловые кеши прогреты практически нулевой дисковый IO

default CDS CDS + no-verify

абсолютное время

583 [574 592]

481[473 484]

461[456 474]

загрузка классов

501[491 511]

339[312 366]

301[294 308]

компиляция 051[043 059]

051[044 058]

051[042 060]

56 copy JavaTechDays 2011 Oracle Corporation

Startupдлинные приложения

bull Важно только для коротких приложенийndash Чем дольше работает приложение тем меньше удельные затраты на

загрузку классов и компиляцию

bull Пример 8 часа работает IntelliJ IDEA 10xndash 26600 классов загруженоndash 5315 методов скомпилировано

bull Загрузка классовndash Всего потрачено 202 с ~07 общего времениndash 10 мсек на класс

bull Компиляцияndash Всего потрачено 112 с ~003 общего времениndash 20 мсек на метод

57 copy JavaTechDays 2011 Oracle Corporation

Whats Next

bull Послушать ещёndash JavaOne Moscow (апрель 2011)

bull Проблема со слайдамиndash Найдите нас на конференцииndash Напишите нам письмо

bull Проблема с JDKndash httpopenjdkjavanetndash Задайте вопрос в OpenJDKndash а лучше сделайте патч и дайте его в OpenJDK на review

58 copy JavaTechDays 2011 Oracle Corporation

QA

Page 36: Java Platform Performance BoF - Aleksey Shipilëv · – 2x2 Intel i5 2.6 Ghz, Ubuntu 10.10 i686, JDK 6u25 • Три варианта эксперимента: – 1 экземпляр

44 copy 2011 JavaTechDays Oracle Corporation

JITоптимизации

46 copy 2011 JavaTechDays Oracle Corporation

JITкак писать код

bull Используйте стандартные библиотекиndash Зачем писать собственный стандартный контейнер

bull Используйте высокоуровневый API ndash javautilndash javautilconcurrentndash NIO NIO2ndash вообще библиотеки

bull Код должен правильным и понятнымndash Сначала правильноndash Потом алгоритмически ldquoбыстроrdquondash Код не должен быть JIT-oriented

bull Правильно используйте возможности языкаndash EPIC FAIL штатная передача управления exceptionамиndash FAIL Возврат ldquoисключенияrdquo через return ltкод_ошибкиgtndash FAIL int вместо Enum или boolean

47 copy 2011 JavaTechDays Oracle Corporation

Как получить ассемблерный код метода

ndash Обычным дебаггером )

ndash JVMTI

ndash -XX+PrintAssemblybull httpwikissuncomdisplayHotSpotInternalsPrintAssembly

JITдля любопытных

54 copy JavaTechDays 2011 Oracle Corporation

StartupEclipse

bull Типичная конфигурацияndash 2x2 Intel i5 26 Ghz Ubuntu 1010 i686 JDK 6u25ndash Eclipse JDT (Galileo)

bull Типичные метрикиndash 6000 загруженных классовndash 1000 методов скомпилированоndash 512 Mb зарезервированного пространства в кучеndash 25 Mb кучи использовано после стартапа

bull Известные ldquoпроблемыrdquondash Загрузка и верификация классовndash JIT-компиляция

55 copy JavaTechDays 2011 Oracle Corporation

StartupEclipse

bull Метрика секунд на запуск-завершениеndash Файловые кеши прогреты практически нулевой дисковый IO

default CDS CDS + no-verify

абсолютное время

583 [574 592]

481[473 484]

461[456 474]

загрузка классов

501[491 511]

339[312 366]

301[294 308]

компиляция 051[043 059]

051[044 058]

051[042 060]

56 copy JavaTechDays 2011 Oracle Corporation

Startupдлинные приложения

bull Важно только для коротких приложенийndash Чем дольше работает приложение тем меньше удельные затраты на

загрузку классов и компиляцию

bull Пример 8 часа работает IntelliJ IDEA 10xndash 26600 классов загруженоndash 5315 методов скомпилировано

bull Загрузка классовndash Всего потрачено 202 с ~07 общего времениndash 10 мсек на класс

bull Компиляцияndash Всего потрачено 112 с ~003 общего времениndash 20 мсек на метод

57 copy JavaTechDays 2011 Oracle Corporation

Whats Next

bull Послушать ещёndash JavaOne Moscow (апрель 2011)

bull Проблема со слайдамиndash Найдите нас на конференцииndash Напишите нам письмо

bull Проблема с JDKndash httpopenjdkjavanetndash Задайте вопрос в OpenJDKndash а лучше сделайте патч и дайте его в OpenJDK на review

58 copy JavaTechDays 2011 Oracle Corporation

QA

Page 37: Java Platform Performance BoF - Aleksey Shipilëv · – 2x2 Intel i5 2.6 Ghz, Ubuntu 10.10 i686, JDK 6u25 • Три варианта эксперимента: – 1 экземпляр

46 copy 2011 JavaTechDays Oracle Corporation

JITкак писать код

bull Используйте стандартные библиотекиndash Зачем писать собственный стандартный контейнер

bull Используйте высокоуровневый API ndash javautilndash javautilconcurrentndash NIO NIO2ndash вообще библиотеки

bull Код должен правильным и понятнымndash Сначала правильноndash Потом алгоритмически ldquoбыстроrdquondash Код не должен быть JIT-oriented

bull Правильно используйте возможности языкаndash EPIC FAIL штатная передача управления exceptionамиndash FAIL Возврат ldquoисключенияrdquo через return ltкод_ошибкиgtndash FAIL int вместо Enum или boolean

47 copy 2011 JavaTechDays Oracle Corporation

Как получить ассемблерный код метода

ndash Обычным дебаггером )

ndash JVMTI

ndash -XX+PrintAssemblybull httpwikissuncomdisplayHotSpotInternalsPrintAssembly

JITдля любопытных

54 copy JavaTechDays 2011 Oracle Corporation

StartupEclipse

bull Типичная конфигурацияndash 2x2 Intel i5 26 Ghz Ubuntu 1010 i686 JDK 6u25ndash Eclipse JDT (Galileo)

bull Типичные метрикиndash 6000 загруженных классовndash 1000 методов скомпилированоndash 512 Mb зарезервированного пространства в кучеndash 25 Mb кучи использовано после стартапа

bull Известные ldquoпроблемыrdquondash Загрузка и верификация классовndash JIT-компиляция

55 copy JavaTechDays 2011 Oracle Corporation

StartupEclipse

bull Метрика секунд на запуск-завершениеndash Файловые кеши прогреты практически нулевой дисковый IO

default CDS CDS + no-verify

абсолютное время

583 [574 592]

481[473 484]

461[456 474]

загрузка классов

501[491 511]

339[312 366]

301[294 308]

компиляция 051[043 059]

051[044 058]

051[042 060]

56 copy JavaTechDays 2011 Oracle Corporation

Startupдлинные приложения

bull Важно только для коротких приложенийndash Чем дольше работает приложение тем меньше удельные затраты на

загрузку классов и компиляцию

bull Пример 8 часа работает IntelliJ IDEA 10xndash 26600 классов загруженоndash 5315 методов скомпилировано

bull Загрузка классовndash Всего потрачено 202 с ~07 общего времениndash 10 мсек на класс

bull Компиляцияndash Всего потрачено 112 с ~003 общего времениndash 20 мсек на метод

57 copy JavaTechDays 2011 Oracle Corporation

Whats Next

bull Послушать ещёndash JavaOne Moscow (апрель 2011)

bull Проблема со слайдамиndash Найдите нас на конференцииndash Напишите нам письмо

bull Проблема с JDKndash httpopenjdkjavanetndash Задайте вопрос в OpenJDKndash а лучше сделайте патч и дайте его в OpenJDK на review

58 copy JavaTechDays 2011 Oracle Corporation

QA

Page 38: Java Platform Performance BoF - Aleksey Shipilëv · – 2x2 Intel i5 2.6 Ghz, Ubuntu 10.10 i686, JDK 6u25 • Три варианта эксперимента: – 1 экземпляр

47 copy 2011 JavaTechDays Oracle Corporation

Как получить ассемблерный код метода

ndash Обычным дебаггером )

ndash JVMTI

ndash -XX+PrintAssemblybull httpwikissuncomdisplayHotSpotInternalsPrintAssembly

JITдля любопытных

54 copy JavaTechDays 2011 Oracle Corporation

StartupEclipse

bull Типичная конфигурацияndash 2x2 Intel i5 26 Ghz Ubuntu 1010 i686 JDK 6u25ndash Eclipse JDT (Galileo)

bull Типичные метрикиndash 6000 загруженных классовndash 1000 методов скомпилированоndash 512 Mb зарезервированного пространства в кучеndash 25 Mb кучи использовано после стартапа

bull Известные ldquoпроблемыrdquondash Загрузка и верификация классовndash JIT-компиляция

55 copy JavaTechDays 2011 Oracle Corporation

StartupEclipse

bull Метрика секунд на запуск-завершениеndash Файловые кеши прогреты практически нулевой дисковый IO

default CDS CDS + no-verify

абсолютное время

583 [574 592]

481[473 484]

461[456 474]

загрузка классов

501[491 511]

339[312 366]

301[294 308]

компиляция 051[043 059]

051[044 058]

051[042 060]

56 copy JavaTechDays 2011 Oracle Corporation

Startupдлинные приложения

bull Важно только для коротких приложенийndash Чем дольше работает приложение тем меньше удельные затраты на

загрузку классов и компиляцию

bull Пример 8 часа работает IntelliJ IDEA 10xndash 26600 классов загруженоndash 5315 методов скомпилировано

bull Загрузка классовndash Всего потрачено 202 с ~07 общего времениndash 10 мсек на класс

bull Компиляцияndash Всего потрачено 112 с ~003 общего времениndash 20 мсек на метод

57 copy JavaTechDays 2011 Oracle Corporation

Whats Next

bull Послушать ещёndash JavaOne Moscow (апрель 2011)

bull Проблема со слайдамиndash Найдите нас на конференцииndash Напишите нам письмо

bull Проблема с JDKndash httpopenjdkjavanetndash Задайте вопрос в OpenJDKndash а лучше сделайте патч и дайте его в OpenJDK на review

58 copy JavaTechDays 2011 Oracle Corporation

QA

Page 39: Java Platform Performance BoF - Aleksey Shipilëv · – 2x2 Intel i5 2.6 Ghz, Ubuntu 10.10 i686, JDK 6u25 • Три варианта эксперимента: – 1 экземпляр

54 copy JavaTechDays 2011 Oracle Corporation

StartupEclipse

bull Типичная конфигурацияndash 2x2 Intel i5 26 Ghz Ubuntu 1010 i686 JDK 6u25ndash Eclipse JDT (Galileo)

bull Типичные метрикиndash 6000 загруженных классовndash 1000 методов скомпилированоndash 512 Mb зарезервированного пространства в кучеndash 25 Mb кучи использовано после стартапа

bull Известные ldquoпроблемыrdquondash Загрузка и верификация классовndash JIT-компиляция

55 copy JavaTechDays 2011 Oracle Corporation

StartupEclipse

bull Метрика секунд на запуск-завершениеndash Файловые кеши прогреты практически нулевой дисковый IO

default CDS CDS + no-verify

абсолютное время

583 [574 592]

481[473 484]

461[456 474]

загрузка классов

501[491 511]

339[312 366]

301[294 308]

компиляция 051[043 059]

051[044 058]

051[042 060]

56 copy JavaTechDays 2011 Oracle Corporation

Startupдлинные приложения

bull Важно только для коротких приложенийndash Чем дольше работает приложение тем меньше удельные затраты на

загрузку классов и компиляцию

bull Пример 8 часа работает IntelliJ IDEA 10xndash 26600 классов загруженоndash 5315 методов скомпилировано

bull Загрузка классовndash Всего потрачено 202 с ~07 общего времениndash 10 мсек на класс

bull Компиляцияndash Всего потрачено 112 с ~003 общего времениndash 20 мсек на метод

57 copy JavaTechDays 2011 Oracle Corporation

Whats Next

bull Послушать ещёndash JavaOne Moscow (апрель 2011)

bull Проблема со слайдамиndash Найдите нас на конференцииndash Напишите нам письмо

bull Проблема с JDKndash httpopenjdkjavanetndash Задайте вопрос в OpenJDKndash а лучше сделайте патч и дайте его в OpenJDK на review

58 copy JavaTechDays 2011 Oracle Corporation

QA

Page 40: Java Platform Performance BoF - Aleksey Shipilëv · – 2x2 Intel i5 2.6 Ghz, Ubuntu 10.10 i686, JDK 6u25 • Три варианта эксперимента: – 1 экземпляр

55 copy JavaTechDays 2011 Oracle Corporation

StartupEclipse

bull Метрика секунд на запуск-завершениеndash Файловые кеши прогреты практически нулевой дисковый IO

default CDS CDS + no-verify

абсолютное время

583 [574 592]

481[473 484]

461[456 474]

загрузка классов

501[491 511]

339[312 366]

301[294 308]

компиляция 051[043 059]

051[044 058]

051[042 060]

56 copy JavaTechDays 2011 Oracle Corporation

Startupдлинные приложения

bull Важно только для коротких приложенийndash Чем дольше работает приложение тем меньше удельные затраты на

загрузку классов и компиляцию

bull Пример 8 часа работает IntelliJ IDEA 10xndash 26600 классов загруженоndash 5315 методов скомпилировано

bull Загрузка классовndash Всего потрачено 202 с ~07 общего времениndash 10 мсек на класс

bull Компиляцияndash Всего потрачено 112 с ~003 общего времениndash 20 мсек на метод

57 copy JavaTechDays 2011 Oracle Corporation

Whats Next

bull Послушать ещёndash JavaOne Moscow (апрель 2011)

bull Проблема со слайдамиndash Найдите нас на конференцииndash Напишите нам письмо

bull Проблема с JDKndash httpopenjdkjavanetndash Задайте вопрос в OpenJDKndash а лучше сделайте патч и дайте его в OpenJDK на review

58 copy JavaTechDays 2011 Oracle Corporation

QA

Page 41: Java Platform Performance BoF - Aleksey Shipilëv · – 2x2 Intel i5 2.6 Ghz, Ubuntu 10.10 i686, JDK 6u25 • Три варианта эксперимента: – 1 экземпляр

56 copy JavaTechDays 2011 Oracle Corporation

Startupдлинные приложения

bull Важно только для коротких приложенийndash Чем дольше работает приложение тем меньше удельные затраты на

загрузку классов и компиляцию

bull Пример 8 часа работает IntelliJ IDEA 10xndash 26600 классов загруженоndash 5315 методов скомпилировано

bull Загрузка классовndash Всего потрачено 202 с ~07 общего времениndash 10 мсек на класс

bull Компиляцияndash Всего потрачено 112 с ~003 общего времениndash 20 мсек на метод

57 copy JavaTechDays 2011 Oracle Corporation

Whats Next

bull Послушать ещёndash JavaOne Moscow (апрель 2011)

bull Проблема со слайдамиndash Найдите нас на конференцииndash Напишите нам письмо

bull Проблема с JDKndash httpopenjdkjavanetndash Задайте вопрос в OpenJDKndash а лучше сделайте патч и дайте его в OpenJDK на review

58 copy JavaTechDays 2011 Oracle Corporation

QA

Page 42: Java Platform Performance BoF - Aleksey Shipilëv · – 2x2 Intel i5 2.6 Ghz, Ubuntu 10.10 i686, JDK 6u25 • Три варианта эксперимента: – 1 экземпляр

57 copy JavaTechDays 2011 Oracle Corporation

Whats Next

bull Послушать ещёndash JavaOne Moscow (апрель 2011)

bull Проблема со слайдамиndash Найдите нас на конференцииndash Напишите нам письмо

bull Проблема с JDKndash httpopenjdkjavanetndash Задайте вопрос в OpenJDKndash а лучше сделайте патч и дайте его в OpenJDK на review

58 copy JavaTechDays 2011 Oracle Corporation

QA

Page 43: Java Platform Performance BoF - Aleksey Shipilëv · – 2x2 Intel i5 2.6 Ghz, Ubuntu 10.10 i686, JDK 6u25 • Три варианта эксперимента: – 1 экземпляр

58 copy JavaTechDays 2011 Oracle Corporation

QA

Page 44: Java Platform Performance BoF - Aleksey Shipilëv · – 2x2 Intel i5 2.6 Ghz, Ubuntu 10.10 i686, JDK 6u25 • Три варианта эксперимента: – 1 экземпляр