Java cpu load windows

How do I monitor the computer’s CPU, memory, and disk usage in Java?

I would like to monitor the following system information in Java:

  • Current CPU usage** (percent)
  • Available memory* (free/total)

Available disk space (free/total)

*Note that I mean overall memory available to the whole system, not just the JVM.

I’m looking for a cross-platform solution (Linux, Mac, and Windows) that doesn’t rely on my own code calling external programs or using JNI. Although these are viable options, I would prefer not to maintain OS-specific code myself if someone already has a better solution.

If there’s a free library out there that does this in a reliable, cross-platform manner, that would be great (even if it makes external calls or uses native code itself).

Any suggestions are much appreciated.

To clarify, I would like to get the current CPU usage for the whole system, not just the Java process(es).

The SIGAR API provides all the functionality I’m looking for in one package, so it’s the best answer to my question so far. However, due it being licensed under the GPL, I cannot use it for my original purpose (a closed source, commercial product). It’s possible that Hyperic may license SIGAR for commercial use, but I haven’t looked into it. For my GPL projects, I will definitely consider SIGAR in the future.

For my current needs, I’m leaning towards the following:

  • For CPU usage, OperatingSystemMXBean.getSystemLoadAverage() / OperatingSystemMXBean.getAvailableProcessors() (load average per cpu)
  • For memory, OperatingSystemMXBean.getTotalPhysicalMemorySize() and OperatingSystemMXBean.getFreePhysicalMemorySize()
  • For disk space, File.getTotalSpace() and File.getUsableSpace()

The getSystemLoadAverage() and disk space querying methods are only available under Java 6. Also, some JMX functionality may not be available to all platforms (i.e. it’s been reported that getSystemLoadAverage() returns -1 on Windows).

Although originally licensed under GPL, it has been changed to Apache 2.0, which can generally be used for closed source, commercial products.

Скахин Алексей / pihel

Личный блог. Заметки о программировании и не только

Страницы

четверг, 21 ноября 2019 г.

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

Состав кучи

Java Heap разделена на 3 основные части:

    Область Yang
      Eden
      Все объекты изначально попадают в эту область.
      Когда Eden полностью заполняется, срабатывает Minor GC только над областью Yang
      Minor GC всегда происходит с остановкой основного цикла программы (Stop-the-word), но за счет небольшого размера области, сборка происходит быстро.

  • Survivor (выжившие)
    Если на объект имеются ссылки, то он перемещается из Eden в S0 Survivor
    При этом счетчик числа GC у объекта инкрементируется.
    Объекты без ссылок, удаляются из Eden.
    • S0 (From) Когда Eden снова заполняется полностью, снова срабатывает Minor GC
      Теперь он затрагивает области Eden и Survivor

      — Объекты без ссылок удаляются из Eden и Survivor
      — Используемые объекты из S0 и Eden перемещаются в S1 и инкрементируется счетчик
    • S1 (To) После второго Minor GC куча выглядит так:

  • Область Old или Tenured (Штатный)
    После InitialTenuringThreshold операций Minor GC (по умолчанию = 7 ) объект перестает считаться Yang и переносится из области Survivor в постоянную область Old (Tenured)

    — Объем Old области больше, чем Yang (обычно в NewRatio раз = 2) и наполняется медленней
    — Full GC по Old области редки, но достаточно продолжительны
    — Цель настройки объектов программы и GC — минимизировать число Full GC

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

    Названия основных параметров:

    Просмотреть список всех параметров: Если параметр объявлен с «=» , то это значение по умолчанию.
    Если с «:=» , то параметр был переопределен.

    Полное описание всех параметров на сайте oracle.

    Значения, выставляемые по умолчанию:
    * Для серверного ПК:
    — Parallel (Throutput) collector
    — Xms (начальный размер Heap) = 1/64 доступной памяти
    — Xmx (максимальный размер Heap) = 1/4 памяти
    * Для прочих устройств:
    — Serial gc
    — Xm* параметры такиеже

    Вариант оптимизации: устанавливать Xms = Xmx, чтобы ускорить работу программы, за счет уменьшения числа изменений объема памяти

    Виды сборщиков мусора

    Serial

    Parallel

    Parallel Old

    Такой же как «Parallel», но Old GC выполняется параллельно, что еще добавляет пропускной способности.

    Над Old областью также происходит дефрагментация данных, что упрощает поиск свободных мест для будущих объектов:

    Над Yang областью не надо проводить дефргаментацию, т.к. она заполняется перемещением между S0 и S1.

    Concurrent Mark-Sweep

    Этот коллектор используется по умолчанию в серверных приложениях.

    По принципу работы G1 схож с CMS, но имеет ряд преимуществ:
    * Выполняется конкурентно как CMS gc
    * Память дефрагментируется без остановки основного цикла программы
    * Фиксированный (предсказуемый) размер паузы gc
    * Пропускная способность остается достаточно высокой
    * Не требует дополнительных 20% озу, как CMS gc (но все равно нужны 10% = G1ReservePercent)

    Достигается это за счет того, что вся память делится на 2048 регионов (-XX:G1HeapRegionSize) от 1 до 32 МБ (в зависимости от размера кучи).
    Выжившие объекты копируются из своего региона в свободный (дефрагментация), этот процесс дискретный и может быть остановлен в любой момент (фиксированная пауза)

    Желатльно чтобы размер объекта был от 50-100% размера региона. Если объект больше региона, то он будет хранится в смежных регионах, что может вызывать задержки при обработке.

    Параметры коллектора, на которые стоит обратить внимание:

    -XX:MaxGCPauseMillis=200
    Ставьте этот параметр = 90% от необходимого времени отклика

    -XX:ConcGCThreads
    кол-во процессов параллельной обработки регионов

    -XX:InitiatingHeapOccupancyPercent=45
    заполненность heap, после которой начинается gc

    -XX:G1ReservePercent=10
    резерв памяти, для защиты от переполнения

    Полный список параметров и их описание на сайте oracle

    GC в Hive

    В сборке Hadoop от Hortonworks используется G1 gc для Hive
    Сменить GC можно, только с перезапуском сервиса.
    В виду сложности этой операции, проведем тесты с параметрыми G1, которые можно менять прямо во время выполнения запроса.

    Databricks провела тесты сравнения нескольких коллекторов и их параметров.
    По результату исследования был сделан вывод:
    * Лучший коллектор для hadoop — G1
    * Уменьшить % заполняемости heap (InitiatingHeapOccupancyPercent), чтобы gc происходил раньше, что должно уменьшить число долгих full gc
    * Увеличить число параллельных потоков gc (ConcGCThreads) — это увеличит нагрузку на CPU, но ускорит GC

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

    1. Запуск с параметрами по умолчанию: Время GC = 364 407 мс.
    Полный список параметров GC во время работы:
    2. Изменим параметры G1: увеличим число потоков (ConcGCThreads) и установим % памяти на котором будет срабатывать GC на 35 (InitiatingHeapOccupancyPercent) Повторим тотже запрос: Время GC = 382 224 мс. Не смотря на рекомендации, время GC увеличилось.
    Для себя сделал вывод — нет смысла трогать параметры GC в большинстве случаев, если нет явных проблем при сборке мусора.

    Комманды для мониторинга Java из консоли

    PrintCommandLineFlags

    Verbose: gc

    Выводить в консоль подробную информацию о работе GC
    * GC — minor gc над yang областью
    * Full GC — поный gc над Old областью
    [Тип GC heap_до -> после (общий размер heap), время_gc]

    Дополнительные параметры verbose:gc
    * PrintGCTimeStamps — время в секундах с момента старта программы
    * PrintGCDetails — дополнительная информация о затратах CPU
    * PrintGCApplicationsStoppedTime — время работы GC с остановкой программы
    * PrintGCApplicationsConcurrentTime — время на конкурентную работу GC

    HeapDumpOnOutOfMemoryError

    команда Описание
    help Список этих параметров
    JFR.start Стартовать запись Java Flight Recorder
    JFR.stop Остановить запись Java Flight Recorder
    JFR.dump Сохранить запись Java Flight Recorder
    JFR.check Проверка — включен ли Java Flight Recorder?
    VM.native_memory
    VM.check_commercial_features Проверка включенности коммерческих возможностей
    VM.unlock_commercial_features Включить комерческие возможности VM
    ManagementAgent.stop
    ManagementAgent.start_local
    ManagementAgent.start
    Thread.print Получить stacktrace всех потоков. Удобно, если приложение зависло с блокировкой, для определения проблемного места.
    GC.class_stats
    GC.class_histogram
    GC.heap_dump Сделать дамп heap для анализа в VisualVM
    GC.run_finalization
    GC.run Выполнить GC
    VM.uptime Время работы приложения
    VM.flags
    VM.system_properties
    VM.command_line
    VM.version Версия java

    JSTAT

    Консольная утилита для мониторинга GC 1000 — это период обновления монитора

    YGC — число срабатываний Yang GC
    YGCT — время работы Yang GC
    FGC — число срабатываний Full GC
    FGCT — время работы Full GC
    GCT — общее время GC
    S0, S1, E (eden), O (Full) — % утилизации областей Heap

    VisualVM

    Удобное бесплатное приложение от Oracle для анализа Java приложений.
    VisualVM расширяется за счет plugins. Основные, которыми рекомендую пользоваться:

    Overview — общие параметры jvm

    Visual GC — online визуализация и история работы GC в разрезе областей heap

    Sampler — информация о нагрузке на CPU и объеме объектов.
    Замеры происходят с некоторой периодичностью раз в несколько мс, что обеспечивает минимальную нагрузку на приложение, но дает не 100% правильную картину.
    Распределение времени CPU по методам приложения:

    Топ объектов по памяти, без привязки к методам:

    Но тут же можно снять heap dump и узнать реальную картину распредления памяти по методам и объектам:

    Если это оконное java приложение, то сэмплировать можно выбранную часть окна:

    Профилирование
    Профилировщик явно трассирует работу программы, что дает наиболее верный резальтат в сравнении с сэмплированием.
    Для того, чтобы начать трассировать программу, нужно запустить ее с особенными параметрами: После чего к запущенному приложению можно подключиться для анализа из visualvm.
    При запуске можно указать фильтр на определенный класс приложения.
    В отличие от сэплирования, при трассировке, объем объектов можно анализировать в разрезе методов:

    Так же можно анализировать исходящие JDBC запросы:

    Распределение времени CPU:

    Flight Recorder

    Mission Control

    Приложение для анализа трассировок записанных Flight Recorder (.jfr)
    Общая информация о системных показателях: CPU, Memory:

    Топ объектов в heap (можно получить и разрез по методам):

    Распределение времени по объектам:

    Но, похоже, статистики по JDBC нет.

    Мониторинг OS

    Мониторинг CPU, ОЗУ * Procs
    r: число процессов ожидающих выполнение
    b: число спящих процессов
    * Memory
    swpd: зарезервировано виртуальной памяти
    free: свободной памяти
    buff: памяти для буферов
    cache: памяти под кэш
    * Swap
    si: памяти загруженной в озу с диска / сек
    so: памяти выгруженной на диск / сек
    * IO
    bi: число считанных блоков / сек
    bo: число записанных блоков / сек
    * System
    in: плановая смена контекста на новый поток
    cs: внеплановая смена контекста, когда потом с большим приоритетом вытесняет низкоприоритетный
    * % общего времени CPU
    us: время за работой программ
    sy: время работы ОС. Большой % тут означает большое число блокировок при доступе к ресурсам.
    id: Время Idle
    wa: время ожидания IO
    st: Время виртуализации

    Top CPU процессов
    включая строку запуска процесса Потоки процесса
    Получить список потоков, отсортированных по потреблению CPU: В 4 столбце «LWP» находится ID потока.
    Если сделать theatdump процесса через jstack, то можно найти проблемный поток, который грузит CPU.
    Для этого LWP нужно преобразовать из десятичной системы в шестнадцатеритную и найти поток с этим nid (0x3d4a == 15690)

    Nethogs — Топ процессов по использованию сети

    IOTOP — Топ процессов по использованию IO

    Flame Graph

    Flame graph удобный инструмент для визуализации полного стека вызовов linux процессов.
    По оси X — время работы вызова, по оси Y — стек, цветом обозначается область: красное — ядро, другие цвета — язык.
    Пример визуализации для Oracle можно видеть тут

    Я бы хотел показать как создать Flame Graph для Java приложения, т.к. есть особенности:
    1. JVM должна быть запущена с флагом «-XX:+PreserveFramePointer», который поддерживается с JDK 8u60
    2. Нужно скачать и скомпилировать утилиту perf-map-agent
    Она нужна, чтобы получить читаемые названия функций.
    3. Скачать Perl скрипты FlameGraph
    4. Установить пакет perf в Linux

    Пример запуска Spark с параметром PreserveFramePointer Запуск Hive с параметром PreserveFramePointer Далее запускаем проблемный запрос в Hive/Spark.
    Подключаемся по ssh к одной из нод кластера.
    Ищем нужные процессы с запросом (см. п. Мониторинг OS)

    Выполняем perf-map-agent, perf и FlameGraph для процесса $1 Скрипт 60 секунд собирает метрики по процессу и по итогу формируется Flame Graph perf-kernel.svg:

    * Зеленым — работа нашей java программы (в данном случае hive)
    * Красное — вызовы ядра
    Как минимум по этому графику видно:
    1. по оси X нет долгих красных промежутков в конце стека (верхняя часть графика), т.е. процесс выполнял полезную работу, а не тратил время на GC
    2. Последовательные зеленые участки — чтение данных с диска — «org/apache/hadoop/hive/serde2/io/HiveDecimalWritable. getHiveDecimal». Т.е. зависаний на определенном чтений нет нет и данные перебираются успешно

    Примеры полных FlameGraph для Hive и Spark

    Оптимизация работы с памятью в программах

    Слабые ссылки
    Слабые ссылки могут очищаться GC, даже если на них есть другие ссылки в программе.
    Удобно использовать для кэша — даже если объект пропадет из памяти, его всегда можно восстановить.

    * SoftReference — объект будет удален, если JVM очень нужна память и на объект только слабые ссылки
    * WeakReference — объект будет удален, если на объект только слабые ссылки
    * PhantomReference — могут быть удалены в любой момент

    Finalizer
    Finalizer — проблема для GC и создает дополнительную нагрузку.
    Не гарантируется:
    * Когда Finalizer будет вызван
    * Будет ли Finalizer вообще вызван
    * Порядок вызова Finalizer

    Примитивы
    * Используйте литералы, вместо создания строк
    * Используйте глобальную видимость объектов, чтобы их переиспользовать
    * Примитивы работают быстрей, чем объектные аналоги
    * Условия проверки быстрей, генерации и отлова исключений
    * Большое кол-во synchronization блокировок замедляет программу
    * Используйте копирование памяти кусками (arraycopy), вместо построчного

    Особенности JVM IBM AIX

    * типы gc называются по другому, но имеют тот же тип.
    Самое близко к G1 — это balanced.

    * Активируются расширенные логи GC аналогично:
    Но ведутся в формате xml. Визуализировать gc log проще всего тут
    Jstat для online просмотра не поддерживается.

    * Flight Recorder не поддерживается этой JVM. Для мониторинга работы нужно использовать Healthcenter
    Запуск online мониторинга: Накладные расходы при online = 0.4%, при записи в файл = 1%
    Просмотр мониторов происходит через Health Center для Eclipse

    * Для возможности снятия дампов нужно активировать опцию Xdump:heap После этого дамп можно снять консольной командой: Последующий анализ дампа нужно проводить в MemoryAnalyzer плагине для Eclipse
    Передача команд через JCMD не поддерживается.

    * Также активировать Heap Dump, Трассировку и VerboseGc можно из Health Center для Eclipse при активированном online мониторинге.

    Читайте также:  Самый экономичный браузер linux
    Оцените статью