Мониторинг и диагностика производительности в Java SE 6

Использование новых возможностей мониторинга и диагностики производительности из последней версии Java

В платформе Java™ Standard Edition 6 (Java SE) особое внимание уделяется производительности. Платформа содержит расширенный набор инструментов для мониторинга и управления приложениями и решения стандартных проблем. Эта статья знакомит с основами мониторинга и управления приложениями на платформе Java SE и подробно разбирает соответствующие усовершенствования, добавленные в Java SE 6.

Кэти Кегли, инженер-программист, IBM

Кэти Кегли (Cathy Kegley) работает программистом в команде Lotus Expeditor Client в IBM.



Грэг Робертс, штатный инженер-программист, IBM

Грег Робертс (Greg Roberts) работает штатным программистов в команде Lotus Expeditor Client в IBM.



08.05.2008

В версии Java SE 6 особое внимание уделяется производительности. Она содержит расширенный набор инструментов для мониторинга и управления приложения и решения стандартных проблем. Среди усовершенствований платформы:

  • " усовершенствования в API для управления и мониторинга;
  • " официальная поддержка улучшенной версии инструмента для мониторинга JConsole с GUI интерфейсом;
  • " усовершенствованные средства контроля в виртуальной машине Java (JVM).

В статье разбираются основы функциональности для мониторинга и управления, предусмотренной в платформе Java SE, и подробно рассказывается о диагностике производительности и усовершенствованиях в управлении платформой, реализованных в последней версии. В ней также рассматриваются инструменты для диагностики и разрешения проблем, входящие в состав платформы Java SE 6.

Чтобы извлечь максимальную пользу из этой статьи, необходимо обладать хорошим знанием функциональности для мониторинга и управления предыдущих версий Java SE. В разделе Ресурсы приведена дополнительная информация по этому вопросу.

API для мониторинга и управления

В пакете java.lang.management, введенном в Java SE 5, определены девять Mbean-компонентов - т.н. платформенные MBean-компоненты или MXBean-компоненты (см. раздел Ресурсы). Каждый MXBean инкапсулирует отдельную функциональную область виртуальной машины. Начиная с версии Java SE 5 JVM включает встроенный сервер MBean-компонентов - платформенный MBean-сервер (platform MBean server). MBean-компоненты управляются этим репозитарием и там же хранятся. В таблице 1 приведены девять MXBean-компонентов платформы Java:

Таблица 1. Платформенные MBean-компоненты
Интерфейс управленияУправляемый ресурс
ClassLoadingMXBeanзагрузчик классов
CompilationMXBeanкомпилятор
MemoryMXBeanпамять
ThreadMXBeanпотоки
RuntimeMXBeanсреда исполнения (runtime)
OperatingSystemMXBeanоперационная система
GarbageCollectorMXBean"сборщик мусора" (garbage collector)
MemoryManagerMXBeanменеджер памяти
MemoryPoolMXBeanпул памяти

Любое приложение может извлечь и использовать платформенные MBean-компоненты, предоставляемые JVM, получив доступ к экземпляру требуемого компонента и вызывая его соответствующие методы. MXBean-компоненты можно использовать для мониторинга функционирования локальной и удаленной виртуальной машины и получения информации о ней.

Платформенные MBean-компоненты обеспечивают доступ к такой информации, как количество загруженных классов, время работы виртуальной машины, количество использованной памяти и число запущенных потоков, а также статистика о конкуренции между потоками.

Осуществлять мониторинг и управлять ресурсами виртуальной машины можно двумя способами:

  • прямым доступом к интерфейсу MXBean
  • непрямым доступом с использованием MBeanServer

Прямой доступ к интерфейсу MXBean

Можно получить доступ к объекту MXBean из static метода класса-фабрики, предоставляющего прямой доступ к интерфейсам MXBean-компонента на локально запущенной виртуальной машине. Класс ManagementFactory предоставляет статические методы класса-фабрики для получения доступа к MXBean-компонентам. В примере из листинга 1 показано, как получить доступ к RuntimeMXBean-компоненту, используя объект-фабрику, а затем прочитать значение одного из его стандартных атрибутов -VmVendor:

Листинг 1. Прямой доступ к MXBean
RuntimeMXBean mxbean = ManagementFactory.getRuntimeMXBean();

//считывание стандартного атрибута "VmVendor"
String vendor = mxbean.getVmVendor();

Непрямой доступ с использованием интерфейса MBeanServer

Интерфейс платформенного MBeanServer с помощью класса MXBeanServerConnection реализует возможность подключения к удаленной виртуальной машине и доступа к MXBean-компонентам, работающим на удаленной платформе. Для доступа к платформенному MBean-серверу можно использовать метод getPlatformMBeanServer класса ManagementFactory. В листинге 2 показано, как получить доступ к RuntimeMXBean-компоненту, работающему на удаленной виртуальной машине, и считать значение его атрибута VmVendor:

Листинг 2. Непрямой доступ к MXBean
MBeanServerConnection serverConn;

try {
   //подключение к удаленной VM с помощью JMX RMI
   JMXServiceURL url = new JMXServiceURL( "service:jmx:rmi:///jndi/rmi://<addr>");

   JMXConnector jmxConnector = JMXConnectorFactory.connect(url);

   serverConn = jmxConnector.getMBeanServerConnection();

   ObjectName objName = new 
   ObjectName(ManagementFactory.RUNTIME_MXBEAN_NAME);

   //считывание стандартного атрибута "VmVendor"
   String vendor = 
   (String) serverConn.getAttribute(objName, "VmVendor");

} catch (...) { }

В разделе Ресурсы приведена дополнительная информация о MXBean-компонентах и API пакета java.lang.management.

Усовершенствования в API, добавленные в Java SE 6

В Java SE 5 был представлен пакет java.util.concurrent.locks, представляющий инфраструктуру для реализации условий блокировки и ожидания. Эта инфраструктура отличается от встроенной в Java поддержки синхронизации и обеспечивает большую гибкость в использовании блокировок.

В Java SE 6 в пакет java.lang.management была добавлена поддержка классов из пакета java.util.concurrent.locks. Были включены новые классы, предоставляющие информацию о блокировках, а также усовершенствованы интерфейсы ThreadInfo, ThreadMXBean и OperatingSystemMXBean.

В Java SE 6 введены два новых класса:

  • класс LockInfo содержит информацию о блокировке;
  • класс MonitorInfo расширяет LockInfo и содержит информацию о блокировке объекта-монитора.

Класс ThreadInfo использует эти новые объекты с добавлением трех новых методов:

  • метод getLockInfo() возвращает объект LockInfo, которым указанный поток был заблокирован в режиме ожидания;
  • метод getLockedMonitors() возвращает объекты MonitorInfo, которые на данный момент заблокированы указанным потоком;
  • метод getLockedSynchronizers() возвращает объекты LockInfo, представляющие синхронизаторы, доступные потоку и заблокированные им на данный момент.

В версии Java SE 5 метод getThreadInfo класса ThreadMXBean уведомляет только об объекте-мониторе. Поток ожидает этот объект, чтобы эксклюзивно заблокировать его, или наоборот, этот объект-монитор уже заблокирован другим потоком, что мешает текущему потоку продолжить работу. В версии Java SE 6 эти методы были усовершенствованы для уведомления также и об объекте AbstractOwnableSynchronizer, который поток ожидает, чтобы заблокировать.

Четыре новых метода были добавлены в интерфейс ThreadMXBean:

  • метод isObjectMonitorUsageSupported() проверяет, поддерживает ли виртуальная машина мониторинг использования объектов-мониторов;
  • метод isSynchronizerUsageSupported() проверяет, поддерживает ли виртуальная машина мониторинг использования доступных синхронизаторов;
  • метод findDeadlockedThreads() возвращает массив с идентификаторами потоков, попавших в "мертвую" блокировку. Это такие потоки, которые блокируют друг друга, не позволяя получить доступ к объекту-монитору или синхронизатору;
  • метод dumpAllThreads() возвращает информацию о стеке и синхронизации для всех активных "живых" потоков.

Также интерфейс OperatingSystemMXBean был дополнен методом getSystemLoadAverage, возвращающим среднюю загрузку системы за прошедшую минуту.

В дополнение к программной поддержке в Java SE 6 также включено несколько инструментов для диагностики и решения проблем, которые можно использовать для поиска проблем и мониторинга использования ресурсов в JVM. В следующих двух разделах объясняются и демонстрируются некоторые из имеющихся диагностических инструментов.


Java-консоль для мониторинга и управления приложениями (JConsole)

В Java SE 6 включена официальная поддержка инструмента JConsole - консоли для мониторинга и управления, впервые представленной в Java SE 5. JConsole позволяет отслеживать статистику по различным ресурсам виртуальной машины во время работы. Она особенно полезна для поиска симптомов взаимных блокировок, конфликта блокировок, утечек памяти и зациклившихся потоков. Эта консоль может быть подключена к локальной или удаленной виртуальной машине и может использоваться для отслеживания:

  • состояния потока, включая связанные с ним блокировки;
  • использования памяти;
  • информации о "сборке мусора";
  • информации о среде исполнения;
  • информации о JVM.

В следующих подразделах обсуждаются усовершенствования, внесенные в инструмент JConsole в Java SE 6. В разделе Ресурсы приведена дополнительная информация о запуске и использовании JConsole.

Поддержка API Attach

Начиная с версии Java SE 6 в JConsole реализована поддержка нового API-интерфейса Attach. Этот API состоит из двух пакетов: com.sun.tools.attach и com.sun.tools.attach.spi, позволяющих приложениям, реализующим этот API, динамически подсоединяться к указанной виртуальной машине и запускать внутри неё свои агентские модули.

В прошлом приложения, для которых нужно было обеспечить мониторинг с помощью JConsole, необходимо было запускать со специальным флагом -Dcom.sun.management.jmxremote, но теперь этого не требуется. Поддержка динамического подсоединения позволяет JConsole выполнять мониторинг любого приложения, поддерживающего Attach API. Совместимые приложения определяются автоматически при запуске инструмента JConsole.

Усовершенствования в пользовательском интерфейсе и отображении MBean-компонентов

В версии Java SE 6 инструмент JConsole получил обновленный пользовательский интерфейс, сходный с ОС Windows® или рабочим столом GNOME, в зависимости от того, на какой платформе он работает. Снимки экрана, представленные дальше в этой статье, были сделаны на Windows XP и показывают возможности пользовательского интерфейса, измененные с предыдущей версии.

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

  • Overview (обзор);
  • Memory (память);
  • Threads (потоки);
  • Classes (классы);
  • VM Summary (сводка по виртуальной машине);
  • Mbeans (MBean-компоненты).

Вкладка Overview содержит сводку информацию об использовании памяти, потоках, классах и ЦП в графическом формате. На этой вкладке одновременно отображается сводная информация, ранее расположенная на нескольких вкладках. На рисунке 1 показана вкладка Overview для примера приложения:

Рисунок 1. Вкладка Overview в окне JConsole
Рисунок 1. Вкладка Overview в окне JConsole

Кликните, чтобы увидеть увеличенное изображение

Рисунок 1. Вкладка Overview в окне JConsole

Рисунок 1. Вкладка Overview в окне JConsole

На вкладке Overview приведены четыре графика с информацией об использовании ресурсов виртуальной машины с возможностью выбора временного периода, для которого необходимо посмотреть результаты. Первый график Heap Memory Usage (использование памяти в куче) изображает зависимость количества памяти, выделяемой из кучи, в мегабайтах от времени. Этот график очень полезен при поиске утечек памяти. Если в приложении есть утечка памяти, то количество памяти, выделяемой из кучи, со временем будет постоянно расти.

На графике Threads (потоки) построена зависимость количества живых потоков от времени, на графике Classes (классы) показано количество загруженных классов. На графике CPU Usage (использование ЦП) приведено, сколько процентов ресурсов ЦП использовалось приложением на разных этапах его жизненного цикла.

Вкладка VM Summary (сводка по виртуальной машине), показанная на рисунке 2, - еще одно нововведение версии Java SE 6. На ней представлена подробная информация о виртуальной машине, включая общее время работы, информацию о потоках, загруженных классах, статистику использования памяти и сборки мусора, а также информацию об операционной системе.

Рисунок 2. Вкладка VM Summary в окне JConsole
Рисунок 2. Вкладка VM Summary в окне JConsole

Кликните, чтобы увидеть увеличенное изображение

Рисунок 2. Вкладка VM Summary в окне JConsole

Рисунок 2. Вкладка VM Summary в окне JConsole

Усовершенствованная вкладка MBeans (MBean-компоненты) облегчила доступ к атрибутам и методам MBean-компонентов. На ней приведена информация обо всех MBean-компонентах, зарегистрированных на платформе. Все платформенные MBean-компоненты доступны через эту вкладку. На дереве в левой части вкладки изображены все работающие на данный момент MBean-компоненты. При выборе MBean-компонента в таблице справа показывается объект MBeanInfo и дескриптор для него (см. рисунок 3):

Рисунок 3. Вкладка MBean в окне JConsole
Рисунок 3. Вкладка MBean в окне JConsole

Выбрав пункт Attributes (атрибуты), можно просмотреть все атрибуты MBean-компонента, как показано на рисунке 4 для MBean-компонента Threading (отвечающего за потоки):

Рисунок 4. Свойства MBean-компонента
Рисунок 4. Свойства MBean-компонента

Заметим, что атрибуты и их значения, показанные справа, соответствуют значениям атрибутов, доступным через ThreadMXBean API в ранее описанном пакете java.lang.management. Можно получить дополнительную информацию по определенному атрибуту, два раза щелкнув по значению атрибута. Только атрибуты, выделенные полужирным шрифтом, могут быть развернуты. Например, двойной щелчок по значению атрибута AllThreadIds отображает идентификаторы всех 22 потоков, как показано на рисунке 5:

Рисунок 5. Развернутое значение атрибута
Рисунок 5. Развернутое значение атрибута

Изменяемые атрибуты выделены синим цветом. Их значения можно изменить, если щелкнуть по атрибуту мышкой и ввести новое значение. Например, атрибут ThreadContentionMonitoringAvailable, показанный на рисунке 5, можно изменить таким способом из окна JConsole.

Выбрав пункт Operations (методы), можно посмотреть список методов, связанных с этим MBean-компонентом. Методы MBean-компонента отображаются справа как кнопки, и нажатие на кнопку приводит к вызову соответствующего метода. На рисунке 6 показаны методы, доступные для ThreadMXBean-компонента:

Рисунок 6. Методы MBean-компонента
Рисунок 6. Методы MBean-компонента

MBean-компонент HotSpot Diagnostic

В версии SE 6 в JConsole была добавлена поддержка MBean-компонента HotSpot Diagnostic. Этот MBean-компонент был добавлен в последней версии для выполнения различных диагностических действий "на лету". Его API позволяет выполнять дамп кучи и устанавливать другие параметры VM непосредственно во время работы. Доступ к MBean-компоненту HotSpot Diagnostic можно получить на вкладке MBean, развернув пункт com.sun.management и выбрав опцию HotSpotDiagnostic. Методы, доступные для HotSpot Diagnostic MBean-компонента, показаны на рисунке 7:

Рисунок 7. MBean-компонент HotSpot Diagnostic
Рисунок 7. MBean-компонент HotSpot Diagnostic

Поддержка плагинов в JConsole

Начиная с версии Java SE 6 инструмент JConsole включает в себя поддержку плагинов, которая позволяет создавать собственные плагины для JConsole. Например, можно добавить специальную вкладку в главное окно JConsole для доступа к собственным MBean-компонентам, определенным в приложении, и проведения нестандартных операций мониторинга.

Для создания собственного плагина для JConsole необходимо создать класс, наследующий абстрактному классу com.sun.tools.jconsole.JConsolePlugin. В этом классе нужно реализовать два метода, чтобы плагин мог корректно отобразиться в окне JConsole:

  • метод newSwingWorker() возвращает объект SwingWorker, который обновляет пользовательский интерфейс для этого плагина;
  • метод getTabs() возвращает набор вкладок, которые будут добавлены в окно JConsole.

Инструмент JConsole использует для поиска и загрузки классов плагинов собственную функциональность провайдера служб (service-provider mechanism). Поэтому плагин должен быть предоставлен в JAR-файле, содержащем файл META-INF/services/com.sun.tools.jconsole.JConsolePlugin. Этот файл должен содержать список с полными именами классов плагина, при этом на одной строке должно находиться имя одного класса. Для загрузки новых плагинов в окно JConsole эту утилиту нужно запустить из командной строки, используя следующую инструкцию:

jconsole -pluginpath plugin_path

В этой инструкции параметр plugin_path ссылается на путь к каталогу или архиву, содержащему плагин для JConsole. Можно указать сразу несколько путей.

В Java SE 6 уже присутствует плагин JTop - пример плагина для JConsole. Этот плагин показывает использование ЦП потоками, запущенными в текущем приложении. Для запуска утилиты JConsole вместе с плагином JTop можно использовать команду:

jconsole -pluginpath JAVA_HOME/demo/management/JTop/JTop.jar

На рисунке 8 приведен экземпляр JConsole с выбранной вкладкой JTop. В левой колонке отображаются названия всех запущенных потоков. Для каждого потока показано использование ЦП и состояние этого потока. Это представление автоматически обновляется при изменении статистики. Плагин JTop может оказаться полезным при поиске потоков, сильно нагружающих ресурсы ЦП.

Рисунок 8. Плагин JTop для JConsole
Рисунок 8. Плагин JTop для JConsole

Инструменты для мониторинга и решения проблем

Кроме утилиты JConsole, Java SE 6 включает поддержку нескольких других утилит для командной строки. Эти диагностические утилиты могут подключаться к любому приложению, при этом приложение не требуется запускать в специальном режиме. Это позволяет получать дополнительную информацию о приложении, чтобы определить, соответствует ли его поведение ожидаемому. Заметим, что инструменты представлены как экспериментальные и необязательно будут полностью поддерживаться в будущих версиях Java SE.

Инструменты для мониторинга

В Java SE 6 входят три утилиты командной строки, перечисленные в таблице 2, которые могут оказаться полезными для отслеживания статистики по производительности виртуальной машины:

Таблица 2. Инструменты для мониторинга
ИнструментОписание
jpsинструмент для получения статуса процесса JVM
jstatинструмент для мониторинга статистики JVM
jstatdдемон jstat для JVM

Утилита jps выводит список виртуальных машин для текущего пользователя на указанной системе. Это утилита полезна в средах, где виртуальная машина запускается через JNI Invocation API, а не через обычный Java-загрузчик. В этих средах не всегда можно легко опознать Java-процессы в полном списке процессов. Утилита jps снимает эту проблему.

В следующем примере показано, как использовать утилиту jps. Необходимо просто ввести jps в командной строке, и утилита перечислит виртуальные машины и идентификаторы процессов, к которым пользователь имеет доступ, как показано в листинге 3:

Листинг 3. Использование утилиты jps
$ jps
16217 MyApplication
16342 jps

Утилита jstat предоставляет информацию о производительности и потреблении ресурсов работающими приложениями, используя встроенные средства контроля виртуальной машины. Эта утилита полезна для диагностирования проблем с производительностью, особенно связанных с изменением размера кучи и сборкой мусора.

Демон jstatd - это серверное приложение на основе вызова удаленных методов (Remote Method Invocation - RMI), отслеживающее создание и отключение виртуальной машины и предоставляющее интерфейс, позволяющий удаленным средствам мониторинга подключаться к виртуальной машине, запущенной на локальном компьютере. Например, этот демон позволяет утилите jps получить список процессов на удаленной системе.

В разделе Ресурсы приведена дополнительная документация и примеры использования этих инструментов.

Инструменты для решения проблем

В версии Java SE 6 также присутствует ряд инструментов для решения проблем. Эти инструменты, перечисленные в таблице 3, позволяют локализовать участки приложения, которые работают не так, как планировалось:

Таблица 3. Инструменты для решения проблем
ИнструментОписание
jinfoинформация о конфигурации
jhatбраузер дампов кучи
jmapтаблица памяти
jsadebugdдемон для агента, обеспечивающего отладку
jstackинформация о стеке

Утилита командной строки jinfo получает конфигурационную информацию из работающего Java-процесса или аварийного дампа и распечатывает системные свойства или параметры командной строки, использованные для запуска виртуальной машины.

Инструмент jhat предоставляет удобные средства для просмотра топологии объектов в мгновенном снимке кучи. Этот инструмент, представленный в версии Java SE 6 как замена инструмента для анализа кучи (Heap Analysis Tool - HAT), помогает при поиске утечек памяти.

Утилита командной строки jmap выводит статистику использования памяти для запущенной виртуальной машины или core-файла. Эта утилита также может с помощью демона jsadebugd осуществлять запрос к процессу или core-файлу на удаленном компьютере. Инструмент jmap полезен при диагностике чрезмерного использования метода finalize, что может привести к OutOfMemoryError.

Демон-агент, обеспечивающий отладку (serviceability agent debug daemon - jsadebugd) подключается к Java-процессу или core-файлу и выступает в роли отладочного сервера. Эта утилита доступна на данный момент для операционных систем Solaris и Linux®. Удаленные клиенты, такие как jstack, jmap и jinfo, могут подключаться к этому серверу через Java RMI.

Утилита командной строки jstack подключается к указанному процессу или core-файлу и распечатывает стек для всех потоков, включая Java-потоки и внутренние потоки виртуальной машины, а при желании и собственно стековые фреймы. Эта утилита помогает при поиске взаимных блокировок. Она может с помощью демона jsadebugd выполнять запросы к процессу или core-файлу на удаленном компьютере. Утилита jstack используется при диагностике потоков, попавших во взаимную блокировку.

В разделе Ресурсы приведена дополнительная документация и примеры использования этих инструментов.


Заключение

В платформе Java 6 реализован ряд усовершенствований в средствах контроля виртуальной машины, API для управления и инструменты JDK, помогающие найти и диагностировать проблемы с производительностью и памятью в Java-приложениях. В этой статье описываются усовершенствования инфраструктуры Java SE для мониторинга и управления приложениями, и рассматриваются диагностические инструменты для командной строки, доступные программистам.

Средняя скорость работы Java-приложений со временем стабильно растет. Теперь, с выходом Java SE 6, производительность Java стала сравнима с производительностью C или C++. Во многих случаях Java-код работает значительно быстрее. Инструменты, описанные в этой статье, можно использовать, чтобы еще больше оптимизировать производительность. Попробуйте воспользоваться ими, и мы гарантируем, что вы найдете возможности для оптимизации своих приложений, о которых раньше и не подозревали.

Ресурсы

Научиться

Получить продукты и технологии

  • IBM trial software: ознакомительные версии программного обеспечения для разработчика, которые можно загрузить со страницы developerWorks.(EN)

Обсудить

Комментарии

developerWorks: Войти

Обязательные поля отмечены звездочкой (*).


Нужен IBM ID?
Забыли Ваш IBM ID?


Забыли Ваш пароль?
Изменить пароль

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Профиль создается, когда вы первый раз заходите в developerWorks. Информация в вашем профиле (имя, страна / регион, название компании) отображается для всех пользователей и будет сопровождать любой опубликованный вами контент пока вы специально не укажите скрыть название вашей компании. Вы можете обновить ваш IBM аккаунт в любое время.

Вся введенная информация защищена.

Выберите имя, которое будет отображаться на экране



При первом входе в developerWorks для Вас будет создан профиль и Вам нужно будет выбрать Отображаемое имя. Оно будет выводиться рядом с контентом, опубликованным Вами в developerWorks.

Отображаемое имя должно иметь длину от 3 символов до 31 символа. Ваше Имя в системе должно быть уникальным. В качестве имени по соображениям приватности нельзя использовать контактный e-mail.

Обязательные поля отмечены звездочкой (*).

(Отображаемое имя должно иметь длину от 3 символов до 31 символа.)

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Вся введенная информация защищена.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=40
Zone=Технология Java
ArticleID=307158
ArticleTitle=Мониторинг и диагностика производительности в Java SE 6
publish-date=05082008