Upload
others
View
4
Download
0
Embed Size (px)
Citation preview
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
58 copy JavaTechDays 2011 Oracle Corporation
QA