Оптимизация производительности: эффективное взаимодействие с виртуальной машиной [email protected] Sun Microsystems Почему • на одной машине работает быстрее, чем на другой? • падает производительность? • периодически падает время отклика приложения и оно увеличивается? • растет объем используемой памяти? • ... Как понять в чем причина и нужно ли что-то менять в вашем приложении? 2 Содержание • • • • Архитектура HotSpot JVM Эффективное взаимодействие с JIT-компилятором Эффективное взаимодействие со сборщиком мусора "out-of-box" производительность 3 Архитектура HotSpot JVM • Runtime > class loading, ... • Сборщики мусора • Интерпретатор • JIT > client > server 4 Идеальная JVM время, проведенное в JVM → 0 время, потраченное на сборку мусора → 0 количество кеш-промахов → 0 код, генерируемый динамическим компилятором оптимален, учитывает специфику работы приложения • время на переключения между задачами и бесполезное ожидание → 0 • • • • 5 HotSpot - идеальная JVM? “The perfect is the enemy of the good” 6 Содержание • • • • Архитектура HotSpot JVM Эффективное взаимодействие с JIT-компилятором Эффективное взаимодействие со сборщиком мусора "out-of-box" производительность 7 Эффективное взаимодействие с JIT • • • • • • Типы компиляторов Эргономика Escape-анализ Синхронизация Многоуровневая компиляция Что лучше – 32bit или 64bit jvm? 8 Типы компиляторов • client – 32bit > простой, ориентирован на приложения клиентского типа (апплеты, игры) > работает быстро, важна скорость запуска приложений > генерирует менее оптимальный код • server – 32bit, 64bit > сложный, ориентирован на приложения серверного типа (сервера java приложений, ...) > работает дольше, важна производительность создаваемого кода > более серьезный анализ, сбор большей статистики => применение более агрессивных оптимизаций 9 Эргономика • Машины серверного класса памяти >= 2Gb # 2cpu >= 2 • Выбор компилятора платформа архитектура ОС sparc 32-bit Solaris Solaris i586 Linux Microsoft Windows sparc64-bit Solaris Solaris amd64 Linux Microsoft Windows машина клиентского типа сервеного типа client server client server client server client client server server server server server server server server 10 «Какой компилятор работает?» # jinfo JAVA_PID Java System Properties: ... java.vm.version = 14.0-b05 java.vm.name = Java HotSpot(TM) Client VM ... os.name = Linux os.arch = i386 os.version = 2.6.8-24-smp ... java.specification.name = Java Platform API Specification java.class.version = 51.0 java.vm.specification.version = 1.0 sun.arch.data.model = 32 java.specification.vendor = Sun Microsystems Inc. java.vm.info = mixed mode java.version = 1.7.0-ea ... 11 Escape-анализ (1) • Является частью серверного компилятора • Анализ непокидающих объектов для данного метода class Escape1 { Integer val; Escape1 next; Escape1(Integer val) { this.val = val } void example() { Integer i1 = new Integer(1); Integer i2 = new Integer(2); Escape e1 = new Escape1( i1 ); Escape e2 = new Escape1( i2 ); e1.next = e2; next = e2; } } • Oбъект O называется непокидающим для метода M, если: > > > > > выделен внутри метода M не является объектом класса Thread или производного от него не имеет финализатора не сохраняется в статическом поле класса или в поле покидающего объекта не передается другому методу в качестве аргумента, если только достоверно не известно, что O не покидает и этот метод 12 Escape-анализ (2) • Возможные оптимизации: > устранение блокировок на непокидающих объектах > оптимизация ссылок на объекты > в ряде случаяев, размещение объекта в стеке или регистрах, а не в куче (heap) class Escape2 { int fld1, fld2; Escape2(int v1, int v2) { fld1 = v1; fld2 = v2; } static void bigMethod() { // Слишком большой метод, чтобы его встраивать... } } => static void example(int v1, int v2) { Escape2 e1 = new Escape2(v1, 10); Escape2 e2 = new Escape2(v2, 5 - v1); bigMethod(); return e1.fld1 + e2.fld2; } v1 + (5 – v1) = 5 13 Синхронизация Java объектов (1) • операции захвата/освобождения блокировки дорогие • в большинстве случаев захват объекта не является состязательным (contended). Т.е. > либо объект был свободным > либо произошел рекурсивный захват в рамках потока Решение > использование легковесных блокировок – эквивалентны CAS инструкциям - быстро > использование тяжеловесных блокировок, если невозможно использовать легковесные – на порядок медленнее 14 Синхронизация Java объектов (2) • Использование CAS инструкций может быть дорогим на многопроцессорных машинах > Решение — привязанные (biased) блокировки > минус — дорогая операция отката привязки – JVM анализирует статистику откатов связывания и может запретить привязывание блокировки для определенных типов объектов > -XX:+UseBiasedLocking • Адаптивная блокировка / adaptive spinning - выбор между > взаимоблокировкой (spin) для корткого времени удержания while (lockStillInUse); > приостановлением (block) потока в случае длительного времени удержания 15 Производительость привязанных блокировок (1) 2xP4 2xAMD 4xAMD 2xUS-III 1xUS-T1 70 60 50 40 30 20 10 0 -10 -20 DB Jack Javac Jess MTRT JVM98 Scimark JBB2000 JBB2005 Volano 16 Производительость привязанных блокировок (2) 2xP4 2xAMD 4xAMD 2xUS-III 1xUS-T1 300 250 200 150 100 50 0 Scimark2 Monte Carlo Sub-benchmark 17 Синхронизация Java объектов (3) • Пропуск блокировки / lock elision > избежание блокировки над локальными переменными public String getStoogeNames() { Vector v = new Vector(); v.add("One"); v.add("Two"); return v.toString(); } > -XX:+DoEscapeAnalysis • Укрупнение блокировки / lock coarsening > объединение смежных synchronized блоков public void addStooges(Vector v) { v.add("One"); v.add("Two"); } > -XX:+EliminateLocks 18 Советы по синхронизации Сразу расчитывайте на использование вашего кода в многопоточных приложениях > экономить на синхронизации нет смысла > если synchronized не используется, то он ничего не стоит Используйте средства обнаружения состязательных блокировок > DTrace HotSpot monitor-contended-* пробы > JVMStat jstat -J-Djstat.showUnsupported=true -snap <pid> | grep _sync_ 19 Оптимизация arraycopy() • java.lang.System.arraycopy() интенсивно используется в библиотеках JDK и клиентских приложений • предыдущие оптимизации ограничивались inline • в новом HotSpot реализованы ассемблерные процедуры для всех типов данных > предполагает неперекрывающийся блок памяти для массива 20 Многоуровневая компиляция • Идея – использование клиентского компилятора на начальном этапе работы приложения и затем переход к серверному • преимущества > улучшение времени запуска по сравнению с серверным компилятором > улучшение производительности по сравнению с клиентским компилятором • -server -XX:+TieredCompilation • доступна только в jdk7, для 32bit jvm 21 Нужна ли вам 64bit JVM? • только если > необходимо большее адресное пространство > необходим java heap > 4Gb минусы 64bit (-d64) по сравнению с 32bit (-d32) jvm > растет нагрузка на память в силу использования 64bit указателей > выравнивание по границам блока в 64-битном режиме увеличивает размеры объекта > увеличивается число D-cache промахов плюсы 64bit по сравнению с 32bit jvm > в 2 раза больше регистров > могут выигрывать приложения, использующие 64-битные вычисления Cжатые указатели: -XX:+UseCompressedOops – использование 32bit указателей в 64bit jvm – возможность адрессовать до 32Gb памяти 22 Содержание • Архитектура HotSpot JVM • Эффективное взаимодействие с JIT-компилятором • Эффективное взаимодействие со сборщиком мусора • "out-of-box" производительность 23 Эффективное взаимодействие с GC • Принципы работы сборщика мусора • Взаимодействие со сборщиком мусора > > > > > > > > Аллокация объектов Большие объекты NUMA Группировка объектов Обнуление указателей Пулы объектов Явный вызов сборщика мусора Излишняя аллокация • Проблемы с финализацией • Утечка памяти • Заключение 24 Сборка мусора (GC) • Находит и освобождает место занимаемое ненужными объектами > Объекты вне транзитивного замыкания включающего roots (стеки потоков, статические поля классов и т.д.) • Автоматическая и безопасная • Проще, если граф объектов “заморожен” > Stop-the-world паузы • Возможны различные подходы > С дефрагментацией или без > Алгоритмы: copying, mark-sweep, mark-compact, ... > Аллокация: linear, free lists, ... 25 Сборка мусора с поколениями • Молодые и старые объекты содержатся отдельно > В пространствах называемых “поколения” (generations) > Возможны разные алгоритмы для молодого и старого поколения • Слабая гипотеза о поколениях > Большинство объектов временные > Mолодое поколение можно собирать отдельно от старого – Необходимо отслеживать ссылки из старого поколения в молодое – Барьер на запись (write barrier) 26 Фоновая сборка мусора • Уменьшает влияние GC на приложение • Сборка мусора происходит одновременно с работой приложения > Граф объектов модифицируется одновременно со сборкой мусора > GC должен получать уведомления об этих изменениях (барьер на запись) • Если фоновый GC собирает только старшее поколение > Нет необходимости отслеживать изменения в молодом поколении 27 Сборщики мусора в Hotspot VM Алгоритм GC для молодого поколения Алгоритм GC для старого поколения Как включить? Default GC Последовательный Последовательный копирующий mark-sweep compact Concurrent Mark-Sweep Параллельный копирующий Фоновый параллельный -XX:+UseConcMarkSweepGC mark-sweep Incremental Concurrent Mark-Sweep Параллельный копирующий Пошаговый фоновый параллельный marksweep -XX:+UseConcMarkSweepGC –XX:+CMSIncrementalMode Parallel Scavenger Параллельный копирующий Последовательный mark-sweep-compact -XX:+UseParallelGC По умолчанию для -server Parallel Scavenger и Parallel Old Параллельный копирующий Параллельный marksweep-compact -XX:+UseParallelOldGC Фоновый Garbage-First параллельный (G1) инкрементальный копирующий -XX:+UseSerialGC По умолчанию для -client на однопроцессорных машинах Фоновый параллельный -XX:+UseG1GC инкрементальный Скоро в JDK7 копирующий 28 Последовательный/Serial GC • Молодое поколение - последовательный копирующий GC • Старое поколение — Mark-Sweep Compact • отлично подходит для клиентских приложений не требующих много (<200mb) памяти • “stop-the-world” сборщик => длительные паузы при больших объемах 29 Фоновый/Concurrent Mark-Sweep GC • Предназначен для избежания долгих “stop-the-world” пауз • Однако, приводит к увеличению нагрузки на процессор, снижая общее быстродействие - «за все надо платить» 30 Эргономика GC • Выбор сборщика мусора > ParallelGC на серверных машинах при работе с серверным JIT (-server) > иначе – SerialGC • Определение максимального размера памяти (-Xmx) > Serial GC — 64Mb > Parallel GC – клиентская машина — min {¼ RAM, 1Gb} – серверная машина — min {¼ RAM, 32Gb} 31 «Кто убирает ваш мусор?» # jmap JAVA_PID Attaching to process ID 12345, please wait... Debugger attached successfully. Client compiler detected. using thread-local object allocation. Parallel GC with 2 thread(s) Heap Configuration: MinHeapFreeRatio MaxHeapFreeRatio MaxHeapSize NewSize MaxNewSize OldSize NewRatio SurvivorRatio PermSize MaxPermSize ... = = = = = = = = = = 40 70 134217728 (128.0MB) 655360 (0.625MB) 4294901760 (4095.9375MB) 1441792 (1.375MB) 12 8 12582912 (12.0MB) 67108864 (64.0MB) 32 «Netbeans вдруг подвис ...» # jmap -heap NETBEANS_PID Parallel GC with 2 thread(s) Heap Configuration: MinHeapFreeRatio = 40 MaxHeapFreeRatio = 70 MaxHeapSize = 134217728 (128.0MB) NewSize = 0.625MB, MaxNewSize = 4095.9375MB OldSize = 1441792 (1.375MB) PermSize = 12.0MB, MaxPermSize = 64.0MB Heap Usage: PS Young Generation Eden Space: capacity = 7798784 (7.4375MB) used = 4760384 (4.53985595703125MB) free = 3038400 (2.89764404296875MB) 61.040080094537814% used PS Old Generation capacity = 30998528 (29.5625MB) used = 10604488 (10.113227844238281MB) free = 20394040 (19.44927215576172MB) 34.20965021306818% used PS Perm Generation capacity = 26083328 (24.875MB) used = 25991728 (24.787643432617188MB) free = 91600 (0.0873565673828125MB) 99.64881781956659% used ... 33 «Чем забита память?» # jmap -histo NETBEANS_PID ... Object Histogram: Size Count Class description ------------------------------------------------------6371024 54861 * ConstMethodKlass 4834144 54861 * MethodKlass 3589960 44040 char[] 3519960 88375 * SymbolKlass 3470152 18522 int[] 3104776 4772 * ConstantPoolKlass 2160944 4772 * InstanceKlassKlass 2005360 4467 * ConstantPoolCacheKlass 1926008 5607 byte[] 1084200 45175 java.lang.String 630864 8661 java.lang.Object[] 615168 25632 java.util.HashMap$Entry 549208 8004 short[] 522120 6749 java.util.HashMap$Entry[] 465768 19407 java.awt.Rectangle 451880 5135 java.lang.Class 376776 7911 java.lang.Object[] 350552 1511 org.netbeans.editor.DrawEngine$DrawInfo 145152 3024 org.netbeans.editor.DrawEngineLineView ... 34 «Из-за чего переполнен PermGen?» Симптом: Exception in thread X java.lang.OutOfMemoryError: PermGen space # jmap -permstat NETBEANS_PID ... finding class loader instances ... done. computing per loader stat ........done. Computing liveness...........................done. class_loader classes bytes parent_loader alive? type <bootstrap> 1189 2727472 null live <internal> 0xee431d58 1 1392 0xee22b3d0 dead sun/reflect/DelegatingClassLoader@0xd4042360 0xee3fbd08 1 1400 0xee227418 dead sun/reflect/DelegatingClassLoader@0xd4042360 ... total = 65 2303 5900688 N/A alive=11, dead=54 N/A 35 «Хотите знать больше про мусор?» • • • • • • • -verbose:gc -XX:+PrintGC -XX:+PrintGCDetails -XX:+PrintHeapAtGC -XX:+PrintGCTimeStamps jconsole jvisualVM 36 Эффективное взаимодействие с GC • Принципы работы сборщика мусора • Взаимодействие со сборщиком мусора > > > > > > > > Аллокация объектов Большие объекты NUMA Группировка объектов Обнуление указателей Пулы объектов Явный вызов сборщика мусора Излишняя аллокация • Проблемы с финализацией • Утечка памяти • Заключение 37 Что создает работу для GC? • Аллокация > Большие объемы аллокации подразумевают большее количество GC • Объем живых данных > Сложность GC пропорциональна • Изменение ссылок в объектах > Больше влияет на приложение, чем на GC > Cоздает работу для GC с поколениями/фоновых GC 38 Аллокация объектов (1) • Быстрая аллокация > > > > 10 инструкций без атомарных операций Новый объект выделяется в молодом поколении Не нужно отслеживать изменения ссылок Гораздо быстрее чем стандартные аллокаторы для C/C++ • Быстрое освобождение новых объектов > Сборка молодого поколения Совет > Не бойтесь выделять маленькие объекты для промежуточных результатов > Избегайте бессмысленной аллокации (лишние вызовы GC) 39 Аллокация объектов (2) • Анализ локальности (escape analysis) > Скаляризация > Оптимизация блокировок (lock elision) Совет > используйте неизменяемые маложивущие объекты вместо часто изменяемых долгоживущих объектов > используйте простой код с большим количеством аллокаций вместо сложных конструкций с меньшим количеством аллокаций 40 Большие объекты • Очень большие объекты > дорого аллоцировать – если объект не помещается в молодом поколении > дорого инициализировать (обнуление) • Частая аллокация и освобождение объектов разных размеров приводит к фрагментации > для GC без дефрагментации или с частичной дефрагментацией Совет > избегайте использования больших объектов, но не в ущерб удобству 41 NUMA (1) • Асимметричный доступ к памяти > процессоры имеют разные задержки при доступе к различным участкам памяти > SPARC, Opteron, будущие процессоры Intel • NUMA-аллокатор > память под объект выделяется ближе к процессору на котором выполняется аллоцирующий поток > доступ к объектам быстрее из потока, в котором произведена аллокация • SPECjbb2005: – +40% на 8-socket Opteron (8 узлов) SunFire x4600 – +300% на 72-socket (18 узлов) SunFire E25K 42 NUMA (2) • Включается явно: -XX:+UseNUMA > JDK6u2, для Solaris ≥ 10 > только в Parallel Scavenger > В Linux скоро будет поддерживаться • Паттерн «поставщик-потребитель» (producer-consumer) Создавайте локальную копию объекта, если он будет часто использоваться 43 Группировка объектов • GC старается расположить объекты ближе к тем, кто на них ссылается > На одной странице или даже на одной кэш-линии > Пример: java.util.HashMap.table[] -> java.util.HashMap.Entry -> key, value table[] Entry 1 key 1 value 1 Entry 2 key 2 value 2 > Не делайте излишних оптимизаций • Реализовано в Parallel Scavenger и G1 44 Обнуление ссылок в объектах • Редко помогает GC > GC в состоянии определить доступен ли объект > Делает код менее читаемым > Может породить скрытые ошибки • Исключения > Структуры данных основанные на массивах – Например ArrayList – В этом случае вы сами занимаетесь управлением памятью – Пользуйтесь стандартной библиотекой JDK! > Предотвращение утечки памяти связанной с финализацией 45 Обнуление локальных ссылок • Не является необходимым > JIT-компилятор проводит анализ достижимости – Хотя интерпретатор обычно этого не делает void foo() { int[] array = new int[1024]; populate(array); print(array); // последнее использование // array в методе foo() array = null; // не нужно! // array не будет рассматриваться как живой объект // сборщиком мусора ... } 46 Пулы объектов (1) • Наследие старых ВМ с очень медленной скоростью аллокации • Необходимо помнить > GC с поколениями оптимизированы для работы с маложивущими неизменяемыми объектами > А не с долгоживущими часто модифицируемыми объектами > Локальные объекты могут быть оптимизированы • Неиспользуемые объекты в пулах > Лишняя работа для GC по сканированию/копированию > Не приносят пользы – приложение их не использует 47 Пулы объектов (2) • Исключения > Объекты, которые дорого инициализировать > Объекты, которые связаны с редкими ресурсами (файловые дескрипторы и т.д.). – пулы потоков (thread pools) – пулы соединений к БД > Используйте библиотеки JDK, если это возможно 48 Явный вызов GC (1) • Не используйте явных вызовов GC! > GC обладает информацией – скорость аллокации, заполнение старшего поколения и т.д. > System.gc() может повредить производительности • Исключения > Явный вызов в периоды бездействия приложения • В HotSpot > System.gc() вызывает полный stop-the-world GC > -XX:+DisableExplicitGC позволяет игнорировать System.gc() 49 Явный вызов GC (2) • Фоновые GC > Разработаны для того, чтобы избегать полных GC > System.gc() делает полное GC! • В HotSpot (для Concurrent Mark Sweep) > -XX:+ExplicitGCInvokesConcurrent Остерегайтесь > библиотек, которые вызывают System.gc() 50 Излишняя аллокация (1) Избегайте ненужных аллокаций двойная аллокацию массива: ArrayList<String> list = new ArrayList<String>(); list.ensureCapacity(1024); правильная версия: ArrayList<String> list = new ArrayList<String>(1024); 51 Излишняя аллокация (2) Старайтесь реалистично оценивать размер структур данных ArrayList<String> list = new ArrayList<String>(1024); Чем чревато добавление 1,000,000 строк в list? > произойдет несколько операций по увеличению размера массива > многократная аллокация нескольких больших массивов > многократное копирование содержимого > потенциальная фрагментация памяти 52 Эффективное взаимодействие с GC • Принципы работы сборщика мусора • Взаимодействие со сборщиком мусора > > > > > > > > Аллокация объектов Большие объекты NUMA Группировка объектов Обнуление указателей Пулы объектов Явный вызов сборщика мусора Излишняя аллокация • Проблемы с финализацией • Утечка памяти • Заключение 53 Финализация • Метод оповещения приложения о недоступности объекта • Основное применение – освобождение системных ресурсов • Финализируемые объекты – все с непустым методом finalize() 54 Аллокация / Освобождение • Аллокация финализируемых объектов > Существенно медленнее > VM должна их отслеживать • Освобождение финализируемых объектов > Не менее двух циклов сборки мусора > 1-й цикл – Идентифицирует объект как недоступный – Помещает объект в очередь для финализации > 2-й цикл – Освобождает объект после выполнения метода finalize() – Если finalize() не сделает объект вновь доступным > Между этими циклами может пройти неопределенное количество времени и сборок мусора 55 Финализация и системные ресурсы • Использование финализации для управления системными ресурсами > Требует GC перед тем, как объект будет финализирован > GC вызывается, когда заканчивается память > Памяти обычно больше чем других системных ресурсов Совет > Управляйте ресурсами явно – используйте пулы 56 Эффективное взаимодействие с GC • Принципы работы сборщика мусора • Взаимодействие со сборщиком мусора > > > > > > > > Аллокация объектов Большие объекты NUMA Группировка объектов Обнуление указателей Пулы объектов Явный вызов сборщика мусора Излишняя аллокация • Проблемы с финализацией • Утечка памяти • Заключение 57 Утечка памяти • GC собирает все недоступные объекты • Но он не будет собирать объекты, которые все еще доступны! • Утечки памяти в системах со сборкой мусора вызываются > объектами, которые доступны, но не используются > использованием механизмов финализации и объектов-ссылок (временная утечка) 58 Забытые обработчики событий Забытые обработчики событий в Swing, AWT и т.д. { } ImageReader reader = new ImageReader(); cancelButton.addActionListener(reader); Image image = reader.readImage(inputFile); // reader остается достижимым пока // cancelButton достижима Удаляйте более не используемые обработчики { } ImageReader reader = new ImageReader(); cancelButton.addActionListener(reader); Image image = reader.readImage(inputFile); cancelButton.removeActionListener(reader); 59 Исключения могут менять порядок исполнения (1) try { ImageReader reader = new ImageReader(); cancelButton.addActionListener(reader); Image image = reader.readImage(inputFile); cancelButton.removeActionListener(reader); } catch (IOException e) { // если исключение произошло в readImage() // то reader останется в множестве обработчиков // событий cancelButton } 60 Исключения могут менять порядок исполнения (2) Всегда используйте блок finally: ImageReader reader = new ImageReader(); cancelButton.addActionListener(reader); try { Image image = reader.readImage(inputFile); } catch (IOException e) { ... } finally { cancelButton.removeActionListener(reader); } 61 Управление метаданными (1) • Иногда необходимо: > Ассоциировать метаданные с объектом > В отдельном ассоциативном массиве class ImageManager { private Map<Image,File> map = new HashMap<Image,File>(); public void add(Image image, File file) { ... } public void remove(Image image) { ... } public File get(Image image) { ... } } 62 Управление метаданными (2) • Если не вызвать remove(image)? > Метаданные никогда не будут удалены > Распространенная причина утечек памяти • Хотелось бы: > когда image больше не нужен – контейнер получил нотификацию – удалил соответствующий элемент • Это как раз то, что делает WeakHashMap private Map<Image,File> map = new WeakHashMap<Image,File>(); 63 Поиск утечек памяти • Инструменты мониторинга: jconsole, jstat, visual gc, VisualVM и т.д. • Выясните на какие объекты ушла память > постройте гистограмму классов при помощи jmap > или -XX:+PrintClassHistogram и Ctrl-Break • Определите причины утечки > произведите анализ достижимости при помощи jhat (встроена в VisualVM) 64 Содержание • • • • Архитектура HotSpot JVM Эффективное взаимодействие с JIT-компилятором Эффективное взаимодействие со сборщиком мусора "out-of-box" производительность 65 "out-of-box" производительность • В jdk6 удалось добиться: > На тесте SPECjbb2005 Java 6 на – 40% впереди конкурентов на Intel Core – 30% впереди конкурентов на процессоре AMD Opteron. > На тесте SciMark Java 6 на – 40% впереди конкурентов > На тесте VolanoMark Java 6 – быстрее Java версии 5 на 20% > http://blogs.sun.com/vmrobot/entry/производительность_jvm_6_0 • JavaSE 6 performance releases > Специальные версии Java SE с последними улучшениями в производительности > http://java.sun.com/javase/technologies/performance.jsp 66 Normalized to IBM SDK 5.0 32-bit Linux SPECjbb2005 140 120 100 114.89 100.43 100 89.68 88.8 80 71.2 60 54.98 J2SE 5.0_08 Java SE 6 RC1 IBM 5.0 SR2 BEA JRockit 5.0_06 R26.4 40 20 0 53.83 32-bit JVM 64-bit JVM 67 SciMark2 Normalized to IBM SDK 5.0 32-bit Linux 120 100 112.79 100 105.26 104.9 60 59.57 56.84 J2SE 5.0_08 Java SE 6 RC1 IBM 5.0 SR2 BEA JRockit 5.0_06 R26.4 40 20 0 79.09 77.07 80 32-bit JVM 64-bit JVM 68 Normalized to IBM SDK 5.0 32-bit Linux Volano 2.5.0.9 119.97 120 100 113.02 110.71 100 96.06 112.02 96.69 88.93 80 60 J2SE 5.0_08 Java SE 6 RC1 IBM 5.0 SR2 BEA JRockit 5.0_06 R26.4 40 20 0 32-bit JVM 64-bit JVM 69 Полезные ссылки (1) • Производительность > http://java.sun.com/javase/technologies/performance.jsp > http://java.sun.com/performance/reference/whitepapers/6_performance.html • Управление памятью > http://java.sun.com/j2se/reference/whitepapers/memorymanagement_whitepape r.pdf > Finalization, Threads, and the Java Technology Memory Model – http://developers.sun.com/learning/javaoneonline/2005/coreplatform/TS-328 1.html > Memory-retention due to finalization article – http://www.devx.com/Java/Article/30192 • OpenJDK > http://www.openjdk.org 70 Полезные ссылки (2) • Средства диагностики и наблюдения > Monitoring and Management in 6.0 http://java.sun.com/developer/technicalArticles/J2SE/monitoring/ > Troubleshooting guide http://java.sun.com/javase/6/webnotes/trouble/ > Jconsole http://java.sun.com/developer/technicalArticles/J2SE/jconsole.html > VisualVM https://visualvm.dev.java.net • Форумы и блоги на русском языке > http://developers.sun.ru > http://blogs.sun.com/vmrobot • Слайды доклада “Оптимизация производительности: эффективное взаимодействие со сборщиком мусора”, конференция TechDays 2008, СанктПетербург http://developers.sun.ru/techdays2008 71 Спасибо! [email protected] Sun Microsystems