78
Вопросы производительности Java приложений Андрей Дмитриев [email protected] http://in4mix2006.narod.ru/ 2008 Copyright (C) 2000 - 2008 Sun Microsystems, Inc. All rights reserved.

Вопросы производительности Java приложений · 2009-11-25 · Использование памяти Количество памяти, требуемое

  • Upload
    others

  • View
    4

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Вопросы производительности Java приложений · 2009-11-25 · Использование памяти Количество памяти, требуемое

Вопросы производительности Java приложений

Андрей Дмитриев[email protected]://in4mix2006.narod.ru/2008

Copyright (C) 2000 - 2008 Sun Microsystems, Inc. All rights reserved.

Page 2: Вопросы производительности Java приложений · 2009-11-25 · Использование памяти Количество памяти, требуемое

Что такое производительность? Вычислительная сложность Использование памяти Скорость запуска приложения Запас прочности и расширяемость Видимая скорость

Page 3: Вопросы производительности Java приложений · 2009-11-25 · Использование памяти Количество памяти, требуемое

Вычислительная сложность Количество операций в

единицу времени Накладные расходы на

вызов методов Сложность алгоритма

для данного класса задач

Page 4: Вопросы производительности Java приложений · 2009-11-25 · Использование памяти Количество памяти, требуемое

Использование памяти Количество памяти, требуемое для обычной

работы программы, должно быть минимизировано

Увеличение нагрузки на систему не должно выражаться в существенном росте потребления памяти

Не должно быть «потерянной памяти» (memory leak)

Page 5: Вопросы производительности Java приложений · 2009-11-25 · Использование памяти Количество памяти, требуемое

Скорость запуска Время, необходимое для запуска приложения

может быть критично Виртуальная машина может оптимизировать

некоторые методы для скорейшего их исполнения

Программа может не обладать всей функциональностью в начале запуска

Page 6: Вопросы производительности Java приложений · 2009-11-25 · Использование памяти Количество памяти, требуемое

Расширяемость

Простота поддержки системы «Предсказуемость» поведения приложения

при повышении нагрузок

Page 7: Вопросы производительности Java приложений · 2009-11-25 · Использование памяти Количество памяти, требуемое

Видимая скорость

Приложение может обладать некими характеристиками, благоприятно влияющими на общее впечатление от программы

Действительная производительность может не соответствовать идеальной картине

Page 8: Вопросы производительности Java приложений · 2009-11-25 · Использование памяти Количество памяти, требуемое

Программа

Введение– Цикл проекта по оптимизации– Инструментарий

Вопросы программирования– Ввод-вывод– Использование памяти– Сложность алгоритма

Использование системных возможностей– Настройки сборщика мусора– Другие возможности виртуальной

машины

Page 9: Вопросы производительности Java приложений · 2009-11-25 · Использование памяти Количество памяти, требуемое

Процесс по оптимизации

• Анализ• Дизайн• Реализация• Тестирование

Page 10: Вопросы производительности Java приложений · 2009-11-25 · Использование памяти Количество памяти, требуемое

Анализ Является первым шагом при

При проектировании При оптимизации

Требует наличия некоторых требований, от которых можно оттолкнуться Минимум памяти Минимальная скорость CPU Минимальная скорость соединения И др.

Profiling – поиск областей, где тратится наибольшее количество ресурсов При профилировании происходит сбор информации о

показателях программы в тех или иных ситуациях Профилирование часто связано с анализом полученных

данных

Page 11: Вопросы производительности Java приложений · 2009-11-25 · Использование памяти Количество памяти, требуемое

Дизайн Создание общей схемы системы с различной

степенью детализации Могут быть использованы различные

методологии При оптимизации это оценка, теоретическое

доказательство предполагаемого подхода

Page 12: Вопросы производительности Java приложений · 2009-11-25 · Использование памяти Количество памяти, требуемое

Реализация Стиль написания или изменения программы

имеет ключевое влияние на качество программы

При оптимизации накладываются качественные рамки в виде тестов на производительность на код

Page 13: Вопросы производительности Java приложений · 2009-11-25 · Использование памяти Количество памяти, требуемое

Тестирование На этапе оптимизации предполагается, что качество

достигло необходимого уровня Построение базы тестов должно начинаться на

самых ранних этапах создания или оптимизации системы

• Benchmarking – сравнение показателей двух различных случаев

Тестирование производительности важнее, чем тестирование качества

Page 14: Вопросы производительности Java приложений · 2009-11-25 · Использование памяти Количество памяти, требуемое

Как оценивать производительность? Запуск приложения Открытие большого

документа Длительность выполнения

запроса И т.п.

Page 15: Вопросы производительности Java приложений · 2009-11-25 · Использование памяти Количество памяти, требуемое

Измерение временных интервалов Инструментирование кода

• Программные вызовы (System.currentTimeMillis()) Системные возможности Эталонные тесты

• Micro benchmark – многократное выполнение конкретного действия

• Macro benchmark - многократное выполнение конкретного действия в совокупности с типичным набором сопутствующих операций

• Сюиты могут выравнивать дисперсию результатов, увеличивая число попыток

Page 16: Вопросы производительности Java приложений · 2009-11-25 · Использование памяти Количество памяти, требуемое

Узкие места программы (hot spot, bottleneck) Это методы или блоки кода, которые

• выполняются дольше всего• вызываются наиболее часто• требуют больше всего памяти

Стратегии• Реализовать эффективнее, сделать

быстрее часто исполняемые методы• Минимизировать число вызовов

медленных методов

Page 17: Вопросы производительности Java приложений · 2009-11-25 · Использование памяти Количество памяти, требуемое

Состояние среды исполненияВозможности VM позволяют:

• составлять слепки области памяти в любой момент времени• считывать данные о загрузке процессора

Page 18: Вопросы производительности Java приложений · 2009-11-25 · Использование памяти Количество памяти, требуемое

Структура области памятиИтоги размещения данных в памяти:> java -Xrunhprof Application Dumping Java heap ... allocation sites ... done.

percent live alloc'ed stack class rank self accum bytes objs bytes objs trace name 1 13.83% 13.83% 221928 3891 221928 3891 300000 char[] 2 5.85% 19.68% 93920 3899 93920 3899 300000 java.lang.String 3 2.19% 21.87% 35112 5 35112 5 305309 byte[] 4 1.60% 23.47% 25600 10 25600 10 300000 byte[] 5 1.18% 24.64% 18856 5 18856 5 305353 byte[] 6 1.02% 25.67% 16400 1 16400 1 305831 int[] 7 0.79% 26.46% 12672 8 55240 32 300045 byte[] 8 0.74% 27.20% 11904 2 11904 2 305389 int[] 9 0.64% 27.84% 10248 427 20544 856 302753 …

Page 19: Вопросы производительности Java приложений · 2009-11-25 · Использование памяти Количество памяти, требуемое

Структура области памяти

Стек вызовов методов в приложении:

TRACE 304224:java.lang.String.<init>(String.java:208)java.lang.StringBuilder.toString(StringBuilder.java:430)

javax.swing.plaf.basic.BasicTextUI.getActionMap(BasicTextUI.java:493)

javax.swing.plaf.basic.BasicTextUI.installKeyboardActions(BasicTextUI.java:378)

Page 20: Вопросы производительности Java приложений · 2009-11-25 · Использование памяти Количество памяти, требуемое

Загрузка процессора

java -Xprof Application Interpreted + native Method 18.5% 0 + 10 sun.awt.Win32GraphicsEnvironment.initDisplay 3.7% 2 + 0 sun.nio.cs.ISO_8859_1$Decoder.decodeArrayLoop 1.9% 0 + 1 sun.awt.windows.WDataTransferer.registerClipboard 1.9% 0 + 1 sun.awt.windows.WComponentPeer.pShow 1.9% 0 + 1 java.lang.ClassLoader$NativeLibrary.load 1.9% 0 + 1 java.lang.ClassLoader$NativeLibrary.find 1.9% 1 + 0 sun.awt.windows.WToolkit.getScreenInsets 1.9% 0 + 1 java.lang.Throwable.fillInStackTrace 1.9% 0 + 1 sun.awt.windows.WFramePeer.setState 1.9% 0 + 1 java.io.WinNTFileSystem.canonicalizeWithPrefix0 …

Page 21: Вопросы производительности Java приложений · 2009-11-25 · Использование памяти Количество памяти, требуемое

Дополнительный инструментарий jmap – утилита для сохранения данных о

структуре данных в куче jhat – анализатор отчетов утилиты jmap JConsole – удаленное профилирование

приложений

Page 22: Вопросы производительности Java приложений · 2009-11-25 · Использование памяти Количество памяти, требуемое

Выводы

Под «производительностью» можно подразумевать различные физические параметры

Приложение может снабжаться своим тестовым набором

JDK поставляется с базовым профилирующим инструментарием

Среда разработки или специализированные приложения могут предоставлять богатые возможности для отладки и профилирования

Page 23: Вопросы производительности Java приложений · 2009-11-25 · Использование памяти Количество памяти, требуемое

Ввод/вывод

Пакет java.io предоставляет широкий спектр классов для работы с потоками данных

Различные классы показывают лучшую производительность для разных задач

Page 24: Вопросы производительности Java приложений · 2009-11-25 · Использование памяти Количество памяти, требуемое

Буферизация данных

Скорость чтения и записи на диск уменьшается при уменьшении блока данных

Создание промежуточного буфера может принести существенное улучшение производительности

Буферизация может осуществляться и средствами самой программы

Page 25: Вопросы производительности Java приложений · 2009-11-25 · Использование памяти Количество памяти, требуемое

Взаимодействие с файловой системой Виртуальная машина сама инициирует

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

повлиять на поведение виртуальной машины Существуют утилиты (filemon),

отслеживающие все обращения указанного процесса к файловой системе

Page 26: Вопросы производительности Java приложений · 2009-11-25 · Использование памяти Количество памяти, требуемое

Использование памяти

Использованная память (RAM footprint) программы включает в себя классы, объекты

Класс java.lang.Runtime предоставляет функциональность для определения свободной и занятой памяти в куче

Для оценки объема памяти, занятой приложением в целом, можно использовать средства платформы

Page 27: Вопросы производительности Java приложений · 2009-11-25 · Использование памяти Количество памяти, требуемое

В памяти VM (heap) можно выделить данные нескольких типов:

Классы Объекты Потоки Системные структуры

данных Системный код и

библиотеки

Из чего состоит занятая память?

Page 28: Вопросы производительности Java приложений · 2009-11-25 · Использование памяти Количество памяти, требуемое

Размер объекта Определяется суммой размеров всех полей

класса (включая super) Виртуальная машина может выравнивать

блокиclass DataStorage{ int index; //4 байта byte value; //1 байт float rgbModel; //4 байта double cmyModel; //8 байт long nativeData; //8 байт //super -ссылка (обычно 4 байта)}

Page 29: Вопросы производительности Java приложений · 2009-11-25 · Использование памяти Количество памяти, требуемое

Размер класса

Класс содержит: байткод структуру методов и полей класса

(необходима VM) данные из пула констант предкомпилированный код (Just-In-Time, JIT)

Page 30: Вопросы производительности Java приложений · 2009-11-25 · Использование памяти Количество памяти, требуемое

Загрузка классов Виртуальная машина загружает классы по

мере необходимости Подсчет количества классов позволяет

оценить суммарный объем Особенно важен при работе по сети

Page 31: Вопросы производительности Java приложений · 2009-11-25 · Использование памяти Количество памяти, требуемое

Список загруженных классов

Команда java –verbose Application составляет список всех классов, загруженных в

память в данном сеансе работы.[Loaded sun.swing.CachedPainter from C:\jdk1.6.0\jre\lib\rt.jar][Loaded javax.Painter from C:\jdk1.6.0\jre\lib\rt.jar][Loaded sun.swing.CachedPainter$Cache from C:\jdk1.6.0\jre\lib\rt.jar][Loaded sun.swing.CachedPainter$Entry from C:\jdk1.6.0\jre\lib\rt.jar][Loaded java.awt.GradientPaint from C:\jdk1.6.0\jre\lib\rt.jar][Loaded java.awt.RenderingHints from C:\jdk1.6.0\jre\lib\rt.jar][Loaded sun.awt.SunHints from C:\jdk1.6.0\jre\lib\rt.jar] …

Page 32: Вопросы производительности Java приложений · 2009-11-25 · Использование памяти Количество памяти, требуемое

Контроль загрузки классов

Загрузка большого количества классов может существенно увеличить объем используемой памяти

Загрузка класса также требует от VM выполнения поисковой операции

Класс загружается при: Создании экземпляра класса Обращении к статическому полю или методу Использовании в instanceof

Работа с объектами из С/С++ кода подчиняется тем же правилам

Page 33: Вопросы производительности Java приложений · 2009-11-25 · Использование памяти Количество памяти, требуемое

Утечка памяти

Обзор Garbage Collector Причины возникновения утечек Способы отслеживания Методы предотвращения утечек

Page 34: Вопросы производительности Java приложений · 2009-11-25 · Использование памяти Количество памяти, требуемое

Сборщик мусора

Технология автоматической сборки объектов, на которые отсутствуют жесткие ссылки позволяет не заботиться об освобождении памяти

У программиста нет надежных способов воздействовать на сборщик мусора

Page 35: Вопросы производительности Java приложений · 2009-11-25 · Использование памяти Количество памяти, требуемое

Как теряется память?

Несмотря на надежность работы GC, количество используемой программой памяти может увеличиваться

Программа может не хранить прямые ссылки на объект, но содержать объект в составе коллекции

При использовании JNI, ресурсы платформы не отслеживаются сборщиком мусора

Page 36: Вопросы производительности Java приложений · 2009-11-25 · Использование памяти Количество памяти, требуемое

Отслеживание утечек

Поиск класса, количество экземпляров которого растет

• Системный ресурс: отслеживание с помощью диспетчера задач

• Java ресурс: отслеживание с помощью профилировщика

Выделение областей в программе, где данные экземпляры создаются

Допустимо контролировать размер всех коллекций

Page 37: Вопросы производительности Java приложений · 2009-11-25 · Использование памяти Количество памяти, требуемое

Предотвращение утечек

Реализация• Применение метода коллекции remove() для

ненужных более объектов Организация проекта

• Создание сюиты нагрузочных тестов для приложения

• Модульное тестирование

Page 38: Вопросы производительности Java приложений · 2009-11-25 · Использование памяти Количество памяти, требуемое

Насколько сильно потоки замедлят мое приложение? Поток занимает место

как объект и требует дополнительной памяти для хранения стека и, возможно, системных ресурсов

Способ реализации потоков заложен в виртуальную машину

Использование потоков может существенно улучшить скорость работы приложения

Page 39: Вопросы производительности Java приложений · 2009-11-25 · Использование памяти Количество памяти, требуемое

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

Задача• Приложение должно

обрабатывать различные типы документов

• Каждому документу назначается класс Translator

• Приложение может реализовать паттерн фабрика, возвращая конкретную реализацию класса Translator

Page 40: Вопросы производительности Java приложений · 2009-11-25 · Использование памяти Количество памяти, требуемое

Неудачное решение

public static Translator getTranslator(String fileType) { if (fileType.equals("doc")) { return new WordTranslator(); } else if (fileType.equals("html")) { return new HTMLTranslator(); } else if (fileType.equals("txt")) { return new PlainTranslator(); } else if (fileType.equals("xml")) { return new XMLTranslator(); } else { return new DefaultTranslator(); } }

При компиляции метода (JIT) загружаются все используемые классы

Page 41: Вопросы производительности Java приложений · 2009-11-25 · Использование памяти Количество памяти, требуемое

Экономичное решение Отложим действия по разрешению нужного

класса до этапа выполнения Для этого используем механизм reflectiontry { if (fileType.equals("doc")) { return (Translator)Class.forName( "WordTranslator").newInstance(); } else if (fileType.equals("html")) { return (Translator)Class.forName("HTMLTranslator").newInstance(); } else if (fileType.equals("txt")) { return (Translator)Class.forName("PlainTranslator").newInstance(); } else if (fileType.equals("xml")) { return (Translator)Class.forName("XMLTranslator").newInstance(); } else { return new DefaultTranslator();}} catch (Exception e) { return new DefaultTranslator();}

Page 42: Вопросы производительности Java приложений · 2009-11-25 · Использование памяти Количество памяти, требуемое

Оценка количества классовПрограмма обрабатывает сообщения от трех

кнопок:public class Listener1 extends JFrame { public Listener1() { JButton open = new JButton("Open"); JButton close = new JButton("Close"); JButton save = new JButton("Save"); getContentPane().setLayout(new FlowLayout()); getContentPane().add(open); getContentPane().add(close); getContentPane().add(save); open.addActionListener(new OpenAction()); //для каждого компонента нужен класс close.addActionListener(new CloseAction()); //если компонентов много, то save.addActionListener(new SaveAction()); //загружается чересчур много классов setVisible(true); }

Page 43: Вопросы производительности Java приложений · 2009-11-25 · Использование памяти Количество памяти, требуемое

Оценка количества классов (cont.)Каждый слушатель – это внутренний класс.

protected void open() { //Open a file } protected void close() { //Close a file } protected void save() { //Save a file }

class OpenAction implements ActionListener { public void actionPerformed(ActionEvent e) { open(); } } class CloseAction implements ActionListener { public void actionPerformed(ActionEvent e) { close(); } }

class SaveAction implements ActionListener { public void actionPerformed(ActionEvent e) { save(); } }

public static void main(String[] args) { new Listener1(); }}

Page 44: Вопросы производительности Java приложений · 2009-11-25 · Использование памяти Количество памяти, требуемое

Совмещение слушателейВнедрение логики в один из классов-слушателей

позволяет переложить на него выбор действия.

class ButtonAction implements ActionListener { public void actionPerformed(ActionEvent e) { String action = (JButton)e.getSource().getText(); if ( action.equals("Open") ) { open(); } else if (action.equals("Close")) { close(); } else if (action.equals("Save")) { save();

Какие сложности привносит данный код в программу?

Page 45: Вопросы производительности Java приложений · 2009-11-25 · Использование памяти Количество памяти, требуемое

Использование общего слушателяТеперь достаточно одного класса для всех

компонентов интерфейса.

ActionListener listener = new ButtonAction();open.addActionListener(listener);close.addActionListener(listener);save.addActionListener(listener);

Page 46: Вопросы производительности Java приложений · 2009-11-25 · Использование памяти Количество памяти, требуемое

Недостатки данного решения

Плохая структурированность программы: блок switch

Зависимость от имен компонентов Сложность поддержки

Page 47: Вопросы производительности Java приложений · 2009-11-25 · Использование памяти Количество памяти, требуемое

Использование отраженияТакже может уменьшить количество классов.

class ReflectiveAction implements ActionListener { String methodName; Object target; public ReflectiveAction(Object target, String methodName) { this.target = target; this.methodName = methodName; } …

Page 48: Вопросы производительности Java приложений · 2009-11-25 · Использование памяти Количество памяти, требуемое

Использование отражения (cont.)Данный метод осуществляет вызов установленного на

этапе создания объекта обработчика для сообщений.

… public void actionPerformed(ActionEvent e) { try { Class[] argTypes = {}; Method method = target.getClass().getMethod(methodName, argTypes); Object[] args = {}; method.invoke(target, args); } catch (Exception ex) { ex.printStackTrace(); }}}

Page 49: Вопросы производительности Java приложений · 2009-11-25 · Использование памяти Количество памяти, требуемое

Использование отражения (cont.)

Потребуется создавать несколько экземпляров для различных компонентов.

open.addActionListener(new ReflectiveAction(this, "open")); close.addActionListener(new ReflectiveAction(this, "close")); save.addActionListener(new ReflectiveAction(this, "save"));

Можно объединять одинаковые компоненты одним таким классом Код не сильно усложняется

Page 50: Вопросы производительности Java приложений · 2009-11-25 · Использование памяти Количество памяти, требуемое

Дальнейшее улучшение

Применить паттерн Заместитель (proxy) для того, чтобы переиспользовать объекты в течение жизни программы

Этим можно достичь константного количества экземпляров классов во время исполнения программы

Page 51: Вопросы производительности Java приложений · 2009-11-25 · Использование памяти Количество памяти, требуемое

Пример: запуск приложений в одной JVM

Каждое Java приложение требует для своей работы JVM

Второе приложение, запущенное стандартным способом, не имеет возможности выполняться внутри уже существующей JVM

Приложения, работающие в разных JVM, не имея возможности их разделять, дублируют все классы

Page 52: Вопросы производительности Java приложений · 2009-11-25 · Использование памяти Количество памяти, требуемое

Структура сложного приложенияСуществует офисный пакет из нескольких

приложений. Электронная таблица:public class Spreadsheet { public static void main(String[] args) { JFrame f = new JFrame("Spreadsheet"); JTable table = new JTable(20,5); JScrollPane scroller = new JScrollPane(table); f.setContentPane(scroller); f.setBounds(10,10,200,200); f.setVisible(true); f.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); }}); } }

Page 53: Вопросы производительности Java приложений · 2009-11-25 · Использование памяти Количество памяти, требуемое

Структура сложного приложения (cont.)Текстовый процессор.public class WordProcessor { public static void main(String[] args) { JFrame f = new JFrame("WordProcessor"); JTextArea text = new JTextArea("Type Here"); JScrollPane scroller = new JScrollPane(text); f.setContentPane(scroller); f.setBounds(10,10,200,200); f.setVisible(true); f.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); }}); } }

Page 54: Вопросы производительности Java приложений · 2009-11-25 · Использование памяти Количество памяти, требуемое

Показатели запуска приложений

> java Spreadsheet > java Wordprocessor

Page 55: Вопросы производительности Java приложений · 2009-11-25 · Использование памяти Количество памяти, требуемое

Реализация запуска в одной JVM

При попытке запустить приложение:

Загрузчик определяет, есть ли уже готовая JVM?

• Если есть, то запустить приложение в ней и выйти

• Если нет, то запустить новую JVM и остаться в памяти слушать последующие обращения

Page 56: Вопросы производительности Java приложений · 2009-11-25 · Использование памяти Количество памяти, требуемое

Класс Launcher В первый раз запускает JVM с сервисом Для взаимодействия использует класс Socket

public class Launcher { static final int socketPort = 9876; public static void main(String[] args) { Launcher l = new Launcher(); l.launch(args[0]); } …

Page 57: Вопросы производительности Java приложений · 2009-11-25 · Использование памяти Количество памяти, требуемое

Класс Launcher (cont.)Попытка найти другие JVM с включенным

сервисом:

public void launch(String className) { boolean launched = false; while (!launched) { Socket s = findService(); if (s != null) { System.out.println("found service"); …

Page 58: Вопросы производительности Java приложений · 2009-11-25 · Использование памяти Количество памяти, требуемое

Класс Launcher (cont.)Передача сервису имени класса приложения,

который нужно запустить:

OutputStream oStream = s.getOutputStream();byte[] bytes = className.getBytes();oStream.write(bytes.length);oStream.write(bytes);oStream.close();launched = true;System.out.println(className);

Page 59: Вопросы производительности Java приложений · 2009-11-25 · Использование памяти Количество памяти, требуемое

Класс Launcher (cont.)Если сервиса еще нет, то создаем его:System.out.println("Starting new service");ServerSocket server = new ServerSocket(socketPort);Launcher.go(className);Thread listener = new ListenerThread(server);listener.start();launched = true;System.out.println("started service listener");

Page 60: Вопросы производительности Java приложений · 2009-11-25 · Использование памяти Количество памяти, требуемое

Сервисный классКласс постоянно находится в ожидании подключения по

сети.public class ListenerThread extends Thread { ServerSocket server; public ListenerThread(ServerSocket socket) { this.server = socket; } public void run() { while (true) { … String className = new String(bytes); Launcher.go(className); }}

Page 61: Вопросы производительности Java приложений · 2009-11-25 · Использование памяти Количество памяти, требуемое

Запуск работающей JVMПриложение запускается посредством

обращения к его методу main() через механизм отражения.

class Launcher… public static void go(final String className) { Thread thread = new Thread() { public void run() { Class clazz = Class.forName(className); Method method = clazz.getMethod("main", {String[].class}); method.invoke(clazz, {new String[0]}); } thread.start(); }

Page 62: Вопросы производительности Java приложений · 2009-11-25 · Использование памяти Количество памяти, требуемое

Результат работы загрузчикаПриложения разделяют

ресурсы между собой.

Page 63: Вопросы производительности Java приложений · 2009-11-25 · Использование памяти Количество памяти, требуемое

Изменяемость объекта

Объект может обладать свойством сохранять свое состояние без изменения• По статистике, такие объекты существуют недолго• Наоборот, изменяемый объект предназначен для

длительной работы VM осуществляет мощных оптимизации над неизменяемыми

объектами Строка – неизменяемый объект Все методы по модификации строки создают новые

объекты

Page 64: Вопросы производительности Java приложений · 2009-11-25 · Использование памяти Количество памяти, требуемое

Неизменяемое значение или ссылка?Модификатор final предотвращает изменение:

public class Fruits { public static final String[] names = {“apple", “banana"};}

Fruits.names = new String[50]; //запрещеноFruits.names[1] = “grape”; //разрешено

Page 65: Вопросы производительности Java приложений · 2009-11-25 · Использование памяти Количество памяти, требуемое

Кэширование объектов

- это сохранение существующих объектов для дальнейшего возможного их использования

Целесообразность такого шага должна быть оценена на основе числовых оценок

Page 66: Вопросы производительности Java приложений · 2009-11-25 · Использование памяти Количество памяти, требуемое

Алгоритмы и структуры данных Выбор алгоритма

обработки данных может существенно повлиять на производительность.

Принцип организации данных в коллекциях объектов важен для выбора подходящей реализации.

Page 67: Вопросы производительности Java приложений · 2009-11-25 · Использование памяти Количество памяти, требуемое

Два алгоритма подсчета суммы прогрессии public class SimpleSummer { public long sum(int start, int stop){ long acc = 0; for(int i=start;i<=stop;i++) acc += i; return acc; } } public class FormulaicSummer { public long sum(int start, int stop){ int bigseries = stop*(stop+1)/2; start--; int littleseries = start*(start+1)/2; return bigseries-littleseries; } }

Page 68: Вопросы производительности Java приложений · 2009-11-25 · Использование памяти Количество памяти, требуемое

Рекурсия

Вызов функцией самой себя естественным образом накладывается на некоторые прикладные задачи

Эффективность рекурсии должна быть оценена с позиции:• использования памяти (метод может использовать

промежуточные данные)• глубины (стек вызовов требует больше памяти)

Page 69: Вопросы производительности Java приложений · 2009-11-25 · Использование памяти Количество памяти, требуемое

Выбор структуры данных

Набор коллекций (пакет java.util) Java состоит из:Списков (List)Множеств (Set)Ассоциативных массивов (Map)

Каждый тип содержит несколько различных реализацийПрименимость того или иного конкретного

класса оценивается по роду задачи Поиск Модификация Выборка

Page 70: Вопросы производительности Java приложений · 2009-11-25 · Использование памяти Количество памяти, требуемое

Синхронизация коллекций

Позволяет исключить параллельный доступ к данным коллекции:

import java.util.Collections;List list = Collections.synchronizedList(new ArrayList());

Этим привносятся дополнительные накладные расходы на работу с данными

Page 71: Вопросы производительности Java приложений · 2009-11-25 · Использование памяти Количество памяти, требуемое

Неизменяемые коллекции

Предотвращает изменение данных коллекции

import java.util.Collections;List list = Collections.unmodifiableList(new ArrayList());

Исключаются действия по копированию данных, необходимые поддержания содержимого в необходимом порядке

Page 72: Вопросы производительности Java приложений · 2009-11-25 · Использование памяти Количество памяти, требуемое

Выводы

Производительность алгоритма зависит от области его применения

Коллекции Java предоставляют широкий набор структур, алгоритмов и возможностей для работы с данными

Page 73: Вопросы производительности Java приложений · 2009-11-25 · Использование памяти Количество памяти, требуемое

Системнозависимый код

Использование JNI в Java приложениях может быть оправдано:

Нужно наладить взаимодействие с существующим С кодом

При реализации JVM Стоит задача внедрения JVM в другую программу Вызов функций, специфичных для операционной

системы Доступ к специальным аппаратным устройствам Создание критичных по времени выполнения

частей кода

Page 74: Вопросы производительности Java приложений · 2009-11-25 · Использование памяти Количество памяти, требуемое

Системнозависимый код (cont.)

Вызов Java-Java может быть быстрее Java-C (и С-Java) вызовов в несколько раз

Скорость обработки JNI вызовов находится в зависимости от реализации JVM

Page 75: Вопросы производительности Java приложений · 2009-11-25 · Использование памяти Количество памяти, требуемое

Сборка мусора

Почему нужно иметь в виду данный фактор? Гарантии, даваемые GC Жизненный цикл объекта Ссылки на объекты

Page 76: Вопросы производительности Java приложений · 2009-11-25 · Использование памяти Количество памяти, требуемое

Ссылки по теме

Effective Java, J. Bloch Java Platform performance, S.Wilson, J.Kesselman Java Performance Tuning, Jack Shirazi Ken Arnold, James Gosling, “The Java programming

language”. Richard Jones, “Garbage collection: algorithms for

automatic dynamic memory management”. Liang Sheng, “The Java Native Interface”. Platform Computing. Multithreaded and Networked

Programming, Thomas W. Christopher and George K. Thiruvathukal.

Page 77: Вопросы производительности Java приложений · 2009-11-25 · Использование памяти Количество памяти, требуемое

Q&A

Page 78: Вопросы производительности Java приложений · 2009-11-25 · Использование памяти Количество памяти, требуемое

Вопросы производительности Java приложений

Андрей Дмитриев[email protected]://in4mix2006.narod.ru/2008