Как посмотреть java процессы на linux
Перейти к содержимому

Как посмотреть java процессы на linux

  • автор:

Список java процессов

java грузит почти половину процессора. Интересует, можно ли как-то узнать список запущенных в java процессов. Перегружал tomcat — не помогает.

Отслеживать
11 1 1 золотой знак 2 2 серебряных знака 8 8 бронзовых знаков
задан 27 фев 2015 в 3:47
2,058 7 7 золотых знаков 35 35 серебряных знаков 71 71 бронзовый знак
Можно javamelody это подключить code.google.com/p/javamelody.
27 фев 2015 в 8:43
Почитайте, может, поможет: habrahabr.ru/post/153135
27 фев 2015 в 9:29

1 ответ 1

Сортировка: Сброс на вариант по умолчанию

  1. Подключаемся к процессу JVM с помощью инструментов jconsole или jvisualvm. Получаем возможность online видеть все потоки.
  2. Делаем дамп потоков процесса JVM с помощью утилиты jstack (http://docs.oracle.com/javase/7/docs/technotes/tools/share/jstack.html). Получаем информацию обо всех потоках на момент получения дампа.

P.S. Грузит половину процессора не Java, а исполняемый код приложения. Посмотрите, где больше всего времени проводит JVM, в потоках, исполняющих логику или в потоке GC. Посмотрите на график работы GC. Не слишком ли часто запускается сборщик и много ли памяти он освобождает каждый раз? Включите логирование GC (http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html#DebuggingOptions). Не слишком ли много времени занимает сборка мусора? Далее делайте вывод о том, кто в основном потребляет CPU — основная логика или GC. Оптимизируйте самую ресурсоемкую часть. Повторяйте процесс итеративно до достижения необходимого результата.

P.P.S. Еще есть Java Mission Control. Но сам не пробовал.

Отслеживать
11 1 1 золотой знак 2 2 серебряных знака 8 8 бронзовых знаков
ответ дан 3 мар 2015 в 16:18
13.2k 1 1 золотой знак 28 28 серебряных знаков 28 28 бронзовых знаков

  • java
  • tomcat
  • linux
    Важное на Мете
Похожие

Подписаться на ленту

Лента вопроса

Для подписки на ленту скопируйте и вставьте эту ссылку в вашу программу для чтения RSS.

Дизайн сайта / логотип © 2024 Stack Exchange Inc; пользовательские материалы лицензированы в соответствии с CC BY-SA . rev 2024.3.8.5973

Просмотр и управление процессами Linux с помощью top

Консультация по продукту 1cloud

Top — команда, которая позволяет пользователям отслеживать процессы и использование системных ресурсов в Linux. Это один из самых полезных инструментов и он поставляется в каждом дистрибутиве. В отличие от других команд она является интерактивной, и вы можете просматривать список процессов, завершать процессы и сортировать. Утилита установлена по умолчанию. Запускается она командой top. Интерфейс команды top после запуска выглядит так: Интерфейс можно разделить на две рабочие зоны:

  1. Верхняя рабочая зона содержит сведения о времени работы сервера, свободных и занятых ресурсах, пользователях;
  2. Основная рабочая зона — это динамически обновляемая таблица, содержащая сведения о процессах.

В верхнем левом углу экрана отображено текущее время — 16:10:23, за которым следует время безотказной работы системы, в нашем примере — 7 дней 14 часов 54 минуты. Далее в строке идет количество активных сеансов пользователя.

В разделе Tasks отображается статистика процессов, выполняемых в вашей системе. Далее перечислено общее количество процессов, активные, спящие, остановленные и процессы-зомби.

Раздел использования CPU показывает процентное время процессорного времени, затрачиваемого на различные задачи.

Последние 2 строки показывают информацию об использовании памяти в системе. Строки Mem и Swap отображают информацию о RAM и области подкачки соответственно. Указаны значения общего, свободного, используемого объема и кеша. Avail Mem — это объем памяти, который может быть выделен для процессов, не использую большую область диска.

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

Значение столбцов указаны в следующей таблице.

PID Это идентификатор процесса, уникальное положительное целое число, которое идентифицирует процесс.
USER Это эффективное имя пользователя (соответствующее идентификатору пользователя) пользователя, который запустил этот процесс. Linux назначает реальный идентификатор пользователя и эффективный идентификатор пользователя для процессов; последний позволяет процессу действовать от имени другого пользователя. Например, пользователь, не являющийся пользователем root, может с правами root установить пакет.
PR Поле показывает приоритет выполнения процесса с точки зрения ядра.
NI Поле показывает nice-значение процесса.
VIRT Общий объем памяти, потребляемый процессом.Он включает в себя код программы, данные, хранящиеся в памяти, а также любые области памяти, которые были подкачены на диск.
RES Количество памяти, потребляемая процессом в оперативной памяти.
SHR Объем памяти, совместно используемый другими процессами.
S В этом поле отображается состояние процесса в однобуквенной форме(R — Runnable, D — Interruptible sleep, S — Uninterruptible sleep, T — Stopped, Z — Zombie).
%CPU Параметр выражает объем в процентах от общей доступной оперативной памяти ОЗУ.
%MEM Параметр выражает значение RES в процентах от общей доступной оперативной памяти.
TIME+ Общее время процессора, используемое процессом с момента его начала, с точностью до сотых долей секунды.
COMMAND Здесь отображено название процессов.

Остановка (kill) сервисов

Если вы хотите остановить процесс, просто нажмите k, во время работы утилиты top. Эта опция вызовет подсказку, в которой будет запрашиваться идентификатор процесса, введите его и нажмите enter. В нашем примере, мы останавливаем работу текстового редактора vim.

Пример остановки vim

Затем введите сигнал, с помощью которого процесс должен быть убит. Если вы оставите поле пустым, то будет использоваться SIGTERM. Если вы хотите принудительно убить процесс, вы можете ввести здесь SIGKILL. Также можно использовать номер сигнала. Например, номер для SIGTERM равен 15, а SIGKILL — 9.

Примечание: если вы оставите идентификатор процесса пустым и нажмете Enter, то завершится самый верхний процесс в списке.

Сортировка списка процессов

Одной из наиболее частых причин использования такого инструмента top является выяснение того, какой процесс потребляет большинство ресурсов. Вы можете нажать следующие клавиши, чтобы отсортировать список:

  • M — для сортировки по памяти;
  • P — для сортировки по использованию CPU;
  • N — для сортировки по идентификатору процесса;
  • T — сортировать по времени работы.

По умолчанию результаты отображаются в порядке убывания, однако вы можете отсортировать в порядке возрастания, нажав R.

Дополнительные возможности

По умолчанию top не показывает полный путь к программе и не делает различие между процессами ядра и процессами пользовательского пространства. Если вам нужна эта информация, нажмите c. Нажмите c еще раз, чтобы вернуться к отображению по умолчанию.

Иногда в процессе работы может понадобиться иерархия процессов child-parent. Вы можете раскрыть ее с помощью клавиш V во время работы top.

Чтобы вывести процессы определенного пользователя, нажмите u, затем введите имя пользователя или оставьте его пустым, чтобы отобразить процессы для всех пользователей.

Вы можете нажать t и m, чтобы изменить стиль статистики процессора и памяти.

Изменение стиля

P. S. Другие инструкции:

  • Установка Webmin для управления Linux
  • Установка и настройка Nagios на Ubuntu
  • Аудит процессов Linux с помощью утилиты Autrace
  • Настройка и аудит системы Linux с помощью демона Auditd
  • Создание шифрованного LUKS раздела на Linux

Поделиться в соцсетях:

Средняя оценка: 5,0, всего оценок: 1 Спасибо за Вашу оценку! К сожалению, проголосовать не получилось. Попробуйте позже

Java создает дополнительные процессы в ubuntu server

В общем, есть самописный софт, он берет инфу через socket. Обрабатывает по определенным алгоритмам, сохраняет результаты в MySql. Программа многопоточная, написанна на яве.

На windows работает все хорошо, максимальная загрузка оперативной памяти 2Гб(всего 8Гб) при максимальной нагрузке. Нагрузка на ядро не больше 40% в пиковом режиме. Java —version 10.0.2

Проблема: На ubuntu 16.04, java —version 10.0.2 циклически создаются процессы, спустя 40 минут работы софта оперативная память забивает 8Гб (100% оперативной памяти) и 4 ядра процессора на 100%.

P.S. на «окнах» таких проблем нет. Кто может подсказать, в какую сторону копать? Т.к. в приоритете необходимо использовать ubuntu server, нежели окна. P.S.S Что в окнах, что в ubuntu — mysql-server и софт находятся на одной машине. Но результаты разные.

P.S.S.S Прошу не рекомендовать использовать «Окна»

clydezX
02.09.18 20:42:35 MSK

Используй профилировщик на ubuntu или сними дамп памяти.

dave ★★★★★
( 02.09.18 20:46:28 MSK )

Из бесплатного есть Eclipse MAT, где можно изучать дамп.

dave ★★★★★
( 02.09.18 20:48:00 MSK )

На ubuntu 16.04, java —version 10.0.2 циклически создаются процессы

JVM самопроизвольно процессы не порождает. Копать в сторону скриптов запуска. Может там что-то воде watchdog который смотрит запущен ли процесс и если нет, то запускает процесс повторна, вот там может быть ошибка, в месте где происходит определении выполняется ли уже обработка.

Aber ★★★★★
( 02.09.18 20:50:26 MSK )
Ответ на: комментарий от Aber 02.09.18 20:50:26 MSK

Скрин

clydezX
( 02.09.18 21:03:21 MSK ) автор топика
Ответ на: Скрин от clydezX 02.09.18 21:03:21 MSK

Опра

Причем с оперативной памятью не ясно, бывает, что за 30 мин 8 ГБ, бывает что 2-4 за 30-60 минут.

clydezX
( 02.09.18 21:05:53 MSK ) автор топика
Ответ на: Опра от clydezX 02.09.18 21:05:53 MSK

У тебя там exception вылазит часто. Не может он привести к такому поведению?

dave ★★★★★
( 02.09.18 21:06:54 MSK )
Ответ на: комментарий от dave 02.09.18 21:06:54 MSK

Exeption

Изучали его, данный exeption появляется в тот момент, когда для не го не хватает процессорного времени

clydezX
( 02.09.18 21:07:40 MSK ) автор топика
Ответ на: Exeption от clydezX 02.09.18 21:07:40 MSK

Этот exception неправильный. Он означает, что в логике есть проблема. Не сетевая же ошибка. Код kanni.grand доступен? Что у вас там творится с ним? IDEA его подгружает? Как минимум, она умеет «дизассемблировать» байт-код.

dave ★★★★★
( 02.09.18 21:10:40 MSK )
Ответ на: комментарий от dave 02.09.18 21:10:40 MSK

Есть исходники этого кода, скинуть их не могу сюда, но интересна разница между работой окон с этим кодом, когда данных проблем не возникает и с ubuntu-server

clydezX
( 02.09.18 21:13:33 MSK ) автор топика
Ответ на: Скрин от clydezX 02.09.18 21:03:21 MSK

Нет, не поможет, как это процесс запускается? По крону? Вручную? Какая команда используется? java -jar project-priority-SNAPSHOT. Если используется shell скрипт посмотри в него, как он порождает процессы, есть ли там циклы.

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

Aber ★★★★★
( 02.09.18 21:15:23 MSK )
Последнее исправление: Aber 02.09.18 21:15:35 MSK (всего исправлений: 1)

Ответ на: комментарий от clydezX 02.09.18 21:13:33 MSK

Этот exception и тот стектрейс вверху — зацепки.

И если я правильно понимаю, у вас все же один многопоточный процесс, а не много процессов? htop показывает потоки отдельной строчкой — так сложилось на линуксе исторически.

Если все же один процесс, то еще раз советую снять дамп. Это многое может прояснить. Дамп снимается одной простой командой с консоли. Это не корку сиплюсплюсную снять — на яве все очень быстро снимается. Тем более, один фиг у вас OOM.

dave ★★★★★
( 02.09.18 21:17:52 MSK )
Последнее исправление: dave 02.09.18 21:19:32 MSK (всего исправлений: 1)

Ответ на: комментарий от Aber 02.09.18 21:15:23 MSK

запускался из под пользователя без прав та же ситуация. запускался из под рута: Способ 1: Автостарт с помощью sh скрипта в init.d Способ 2: В ручную java — jar * Результаты одни и те же.

clydezX
( 02.09.18 21:18:12 MSK ) автор топика
Ответ на: Скрин от clydezX 02.09.18 21:03:21 MSK

Всё плохо, программа кривая.

Deleted
( 02.09.18 21:20:01 MSK )
Ответ на: комментарий от clydezX 02.09.18 21:18:12 MSK

В ручную java — jar * Результаты одни и те же.

99.9% ошибка в коде этого приложения, поищи в коде «Runtime.getRuntime().exec» или «new ProcessBuilder», оба метода позволяют породить новый дочерний процесс, посмотри есть ли цикл (наверное есть), посмотри там логику принятия решения о запуске нового дочернего процесса. Хех, по логике цикла там может и не быть, посмотри дерево процессов: ps -aef —forest

Aber ★★★★★
( 02.09.18 21:21:04 MSK )
Последнее исправление: Aber 02.09.18 21:28:50 MSK (всего исправлений: 1)

Джава оракловская или OpenJDK?

Попробуй поменять на другую, может помочь.

timdorohin ★★★★
( 02.09.18 21:27:31 MSK )
Ответ на: комментарий от Aber 02.09.18 21:21:04 MSK

Проверил, данные конструкции присутствуют в используемых библиотеках, но почему windows не создает дочерних процессов и работает нормально?

clydezX
( 02.09.18 21:29:27 MSK ) автор топика
Ответ на: комментарий от timdorohin 02.09.18 21:27:31 MSK

Что в первом, что во втором случае используется Oracle

clydezX
( 02.09.18 21:30:31 MSK ) автор топика
Ответ на: комментарий от clydezX 02.09.18 21:30:31 MSK

Автор пограммы ты?

Deleted
( 02.09.18 21:31:54 MSK )
Ответ на: комментарий от clydezX 02.09.18 21:30:31 MSK

А не видно с какими параметрами новые процессы появляются?

timdorohin ★★★★
( 02.09.18 21:32:06 MSK )
Ответ на: комментарий от Deleted 02.09.18 21:31:54 MSK

Нет, моя задача сервер и веб морда, которая достает с базы данные и приводит их в человеческий вид

clydezX
( 02.09.18 21:35:13 MSK ) автор топика
Ответ на: комментарий от clydezX 02.09.18 21:29:27 MSK

Потому что программисты писали код на windows и не тестировали под linux. Как можно проверить запущен ли экземпляр приложения? Только средствами самой операционной системы. Например можно создать lock файл где-то не проверив работу такой схемы под linux, можно открыть сокет на конкретном порту (другой процесс уже не сможет), и наверное можно проверить по результату вывода команды для отображения списка запущенных процессов (не самый умный способ из-за латентности, и для каждой ос будет совя команда со своим форматом вывода).

Aber ★★★★★
( 02.09.18 21:35:33 MSK )
Последнее исправление: Aber 02.09.18 21:36:40 MSK (всего исправлений: 1)

Ответ на: комментарий от clydezX 02.09.18 21:35:13 MSK

Судя по тому что в названии присутствует слово SNAPSHOT, значит ты работаешь непосредственно трудами с этой командой разработки, самая правильная стратегия просто писать баг репорт на трекере разработчиков, еще кинуть письмо лицу которое исполняет роль project-manager’а с описанием проблемы, чтоб твой баг не «утонул» среди прочих, он как погонщик должен расставить приоритеты и следить чтоб работа была исполнена.

Aber ★★★★★
( 02.09.18 21:41:55 MSK )
Ответ на: комментарий от Aber 02.09.18 21:41:55 MSK

Спасибо за информацию, так и сделаю. Начну продвигать разработку конкретно под ubuntu. Возможно разработку делали именно из под окон и в результате возникает такая проблема. Спасибо всем, кто откликнулся.

clydezX
( 02.09.18 21:46:40 MSK ) автор топика
Ответ на: комментарий от clydezX 02.09.18 21:35:13 MSK

Ну без автора сего чуда ты ничего не сделаешь. Вот тебе гадание:

— Судя по скринам у вас там запускаются потоки, а не процессы (т.к. RES VIRT и т.п. колонки одинаковые, что крайне маловероятно обычно). Убедится можно, скрыв userland threads в настройках htop.

— Судя по логу (это уже совсем гадание), автор программы вполне моет не знать о ThreadPoolExecutor, и воротит потоки примерно как new Thread().start() — что есть не хорошо, но не страшно.

— Судя по результатам, эти потоки «текут» (гугли tread leak).

Почему текут? А тут хз. Судя по тому что автор ПО использует подчёркивания и в именах классов, он в java не местный, и не учится, а значит не умеет писать многопоточный код, возможно где-то race condition, возможно некое исключение (которого не видно, такие авторы часто их молча давят) вылетает и из-за него поток остаётся висеть.

Короче, сам ты тут ничего не сделашь, ну разве что ткнуть автора в его поделку и заставить переедлывать\исправлять. Если ты для него и начальства не авторитет, то можете заказать независимую экспертизу, у какого-нибудь специалиста (лучше сразу у нескольких, а то тоже нарвётесь на такого же), чтобы он вам описал проблемы вашей «программы».

Deleted
( 02.09.18 21:48:45 MSK )
Последнее исправление: Deleted 02.09.18 21:49:55 MSK (всего исправлений: 2)

Ручная кофемолка: инструменты командной строки для Java

В книге «97 вещей, которые должен знать каждый Java-программист» есть глава о некоторых инструментах командной строки в JDK (я дал 2 из 97 советов).

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

Я предпочитаю командную строку для своей повседневной работы, используя комбинацию команд git , sed , grep , и т. д., bash что упрощает выполнение повторяющихся задач.

Уже в «Прагматическом программисте» была четкая ссылка на это в разделе 21:

Используйте возможности командных оболочек+
Используйте оболочку, когда графические пользовательские интерфейсы не подходят.

Также хотелось бы сослаться на книгу NealFord «Productive Programmer»:

Вам не нужно бояться командной строки, это как любой язык программирования. Вы выполняете команды или сценарии и можете комбинировать их ввод и вывод в более сложные процессы. В Linux и OSX вас хорошо обслуживают встроенные bash или zsh, в Windows вы можете воспользоваться либо cmd , либо с недавних пор с подсистемой Windows для Linux (WSL).

Большинство инструментов поставляются со встроенной справкой, отображаемой по параметру -h или предоставляют страницы справки с помощью `man`. Эти справочные страницы также можно найти на веб-сайте Oracle.

Управление установками JDK с помощью SDKman

Как упоминалось в предыдущих статьях, для меня sdkman — это гений управления установками Java, Groovy, Maven, Gradle, Micronaut и многих других инструментов, а также для активации различных версий.

Для этого вы устанавливаете sdkman, например, с помощью:

curl -s «https://get.sdkman.io» | bash .

После этого по команде sdk list отображаются устанавливаемые инструменты, и с помощью команды sdk list java вы можете увидеть доступные и установленные версии JDK.
У вас есть широкий выбор версий JDK от OpenJDK до Azul Zuulu, GraalVM до Amazon и SAP JDK.

С помощью, например sdk install java 17-open , вы можете установить новые версии (вплоть до последней EAP), а с помощью sdk use java 17-open вы можете переключиться на текущую оболочку или глобально.

Простые помощники

В каждом пакете JRE и JDK помимо компилятора javac и среды выполнения java есть много полезных помощников в каталоге bin дистрибутива. Некоторые из них, как jarsigner или keytool очень специфичные, и я не буду углубляться в них здесь.

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

jps

Если вы хотите избавиться от зависшего процесса Java, вы можете либо найти его в диспетчере задач и закрыть его там, либо найти PID (идентификатор процесса) с помощью, ps auxww | grep java , а затем завершить его с помощью `kill`.

Вместо этого встроенный jps может предоставить тот же сервис.
Есть дополнительные параметры: -l — для полного доменного имени основного класса или пути к JAR-файлу запуска, -v — для аргументов JVM и -m — для аргументов командной строки метода main .

jstack

Чтобы получить дамп потока JVM, особенно если он завис в какой-то точке, которую вы хотите изучить более внимательно, есть 2 способа.
Либо `kill -3` производит вывод непосредственно из процесса, либо предпочтительнее с помощью `jstack`.

Таким образом, jstack также может заставить остановившиеся процессы выводить с флагом «force» -F , который затем можно перенаправить в файл.
С помощью `jstack -l` вы получаете дополнительный вывод о блокировках, также отображаются взаимоблокировки.

Статус потоков различается между kill -3 и jstack .

kill -3

jstack

jinfo

С помощью jinfo вы можете быстро получить доступ к системным свойствам, флагам JVM и аргументам JVM процесса Java.

jinfo дает полный обзор, который может помочь в обнаружении странных эффектов. Используя jinfo -flag name=value или -flag [+|-]name вы можете изменить динамические флаги JVM.

jshell

Представленная в Java 9, jshell — это была первая официальная консоль REPL (read eval print loop) для интерактивного выполнения кода Java.
Можно не только вычислять выражения и назначать переменные, но также можно создавать и динамически переопределять классы с методами.

Можно передать пути к классам в jshell, содержимое которого затем будет доступно для импорта и использования.

jshell имеет множество параметров командной строки, а также встроенные команды, которые объясняются с помощью параметра /? .
Особенно полезны /help , /save , /history и команды /vars , /types , /methods , /imports .

Для редактирования больших фрагментов кода вы можете использовать ‘/edit’, создав свой собственный редактор, используя переменные окружения ‘JSHELLEDITOR’, ‘VISUAL’, ‘EDITOR’ или установить редактор указав ‘/path/to/editor’.

Важные пакеты java.util.(*,streams,concurrent) , такие как java.math и некоторые другие, уже импортированы по умолчанию.

Выражения присваиваются заполнителям $5 , которые можно использовать позже.
Для улучшения читабельности кода лучше использовать var начиная с Java 11, тогда переменные можно создавать без объявления типа.
Новые языковые функции, которые все еще доступны в режиме предварительного просмотра, могут быть включены с помощью параметра —enable-preview .

Очень удобной функцией jshell является автодополнение. Каждое имя класса, метода и переменной можно контекстно завершить, нажав несколько раз клавишу Tab.

Вот пример запуска игры «Жизнь» (Покойся с миром — Джон Конвей) в jshell .

// GOL Rules: Cell is alive, if it was alive and has 2 or 3 living neighbours or always with 3 living neighbours import static java.util.stream.IntStream.range; import static java.util.stream.Collectors.*; import static java.util.function.Predicate.*; record Cell(int x, int y) < Stream nb() < return range(x()-1,x()+2) .mapToObj(i -> i) .flatMap(x -> range(y()-1,y()+2) .mapToObj(y -> new Cell(x,y))) .filter(c -> !this.equals(c)); >boolean alive(Set cells) < var count = nb().filter(cells::contains).count(); return (cells.contains(this) && count == 2) || count == 3; >> Set evolve(Set cells) < return cells.stream().flatMap(c -> c.nb()).distinct() .filter(c -> c.alive(cells)) .collect(toSet()); >void print(Set cells) < var min=new Cell(cells.stream().mapToInt(Cell::x).min().getAsInt(), cells.stream().mapToInt(Cell::y).min().getAsInt()); var max=new Cell(cells.stream().mapToInt(Cell::x).max().getAsInt(), cells.stream().mapToInt(Cell::y).max().getAsInt()); range(min.y(), max.y()+1) .mapToObj(y -> range(min.x(), max.x()+1) .mapToObj(x -> cells.contains(new Cell(x,y)) ? "X" : " ") .collect(joining(""))).forEach(System.out::println); >""" # # ### """ var cells = Set.of(new Cell(1,0), new Cell(2,1), new Cell(0,2),new Cell(1,2),new Cell(2,2)) void gen(Set cells, int steps) < print(cells); if (steps>0) gen(evolve(cells),steps-1); >Set parse(String s)

jar

Для работы с jar-файлами (Java ARchive) есть одноименная команда.
Синтаксис командной строки аналогичен команде tar .
Хотя tar по умолчанию только хранит файлы в архиве, jar также сжимает их, что приводит к значительному уменьшению размера.

Вот несколько полезных сценариев использования:

  • jar tf file.jar — отображать содержимое архива
  • jar xvf file.jar — распаковать файл архива в текущем каталоге (с отображением по v )
  • jar uvf file.jar -C path test.txt — добавить файл из указанной директории

Поскольку в Java 9 jar также может создавать мультирелизные архивы, совместимые с несколькими JDK и могут содержать оптимизированные файлы классов для соответствующей версии Java.

java

Команда Java запускает виртуальную машину Java с заданным путем к классам (каталоги, файлы и URL-адреса jar и классов) и основным классом, main метод которого выполняется.

С помощью команды java -jar file.jar main класс определяется с помощью метаинформации файла jar.

Начиная с Java 11, доступен JEP 330 (Запуск программ с однофайловым исходным кодом), поэтому исходные файлы можно запускать напрямую.

cat > Hello.java < hello <<EOF #!/usr/bin/java --source 10 public class Hello < public static void main(String. args) < System.out.println("Hello "+String.join(" ",args)+"!"); >> EOF chmod +x hello ./hello JEP 330

JVM можно контролировать с помощью сотен флагов, от выделения памяти с помощью флагов -Xmx и -Xms до выбора сборщика мусора с помощью флага -XG1GC и настроек журнала.
Коллекция ресурсов по флагам JVM была опубликована Betsy Rhodes на Foojay

Далее следуют несколько полезных флагов, список представляет лишь часть опций JVM.

  • HeapDumpOnOutOfMemoryError
  • Xshareclasses — Обмен данными класса
  • verbose:gc — Ведение журнала GC
  • +TraceClassLoading
  • +UseCompressedStrings

Javac

Компилятор javac транслирует исходный код Java в один или несколько файлов классов, содержащих байт-код классов, выполняет начальную оптимизацию и запускает обработку аннотаций «процессорами аннотаций».
Чтобы указать все классы, от которых зависит текущий код, они или их архивы должны быть перечислены в пути к классам или пути к модулю.

Для более глубокого изучения javac потребуется отдельная статья, поэтому мы остановимся на ее почетном упоминании.

JavaP

Всякий раз, когда вы хотите изучить результат javac , javap вступает в игру.
Этот инструмент позволяет отображать сигнатуру класса, его расположение в памяти с помощью флагов -l -v -constants или инструкциями байт-кода языка стека JVM с помощью флага -c .
Это может быть полезно, если вы хотите увидеть влияние определенных опций компилятора или версий Java, или если изменилось поведение оптимизаций (размер встроенного кода).

В качестве параметра он получает полное имя класса, имя файла или URL-адрес jar.

Вот пример нашего класса Hello.java , где вы можете видеть, например, что Java 14 теперь использует операцию «invokedynamic» для конкатенации строк.

javap -c Hello Compiled from "Hello.java" public class Hello < // Constructor with Super-Constructor call public Hello(); Code: // load "this" on stack 0: aload_0 4: return public static void main(java.lang.String. ); Code: 0: getstatic #7 // Field java/lang/System.out:Ljava/io/PrintStream; 3: ldc #13 // String // load first parameter on stack, i.e. "args" 5: aload_0 6: invokestatic #15 // Method java/lang/String.join:(Ljava/lang/CharSequence;[Ljava/lang/CharSequence;)Ljava/lang/String; // string concatenation 9: invokedynamic #21, 0 // InvokeDynamic #0:makeConcatWithConstants:(Ljava/lang/String;)Ljava/lang/String; 14: invokevirtual #25 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 17: return >

JMAP

Было полезно создавать heapdumps или гистограммы (ссылочных) объектов jmap .
В настоящее время рекомендуется использовать jcmd .

  • jmap -clstats выводит статистику загрузчика классов
  • jmap -histo или jmap -histo:live выводит гистограмму
  • jmap -dump:live,format=b,file=heap.hprof генерирует дамп кучи.

JCMD

Используя jcmd можно управлять Java процессами удаленно, существует довольно много действий, которые можно инициировать в JVM.
jcmd может использоваться интерактивно или с помощью параметров командной строки.

Используя jcmd , можно запускать определенные действия, при этом несколько команд разделяются символами новой строки.
Кроме того jcmd help дает информацию о том, какие команды имеются.

jcmd 14358

Вот несколько примеров:

Подробная информация обо всех загруженных классах

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

Создать дамп кучи.

Обзор использования кучи

Запустить сборку мусора

JFR.start name= settings= delay=20s duration=2m

Начать запись JDK JFR

JFR.dump name= filename=

Создать дамп JFR

Время выполнения JVM

Активные флаги JVM

Командная строка JVM

Визуальный вывод иерархии классов

Управление ведением журнала JVM

jcmd 15254 GC.heap_info 15254: garbage-first heap total 1048576K, used 214334K [0x00000007c0000000, 0x0000000800000000) region size 1024K, 135 young (138240K), 0 survivors (0K) Metaspace used 136764K, capacity 142605K, committed 142896K, reserved 1169408K class space used 19855K, capacity 22505K, committed 22576K, reserved 1048576K
jcmd GradleDaemon GC.class_histogram | head 14358: num #instances #bytes class name ---------------------------------------------- 1: 42635 4515304 [C 2: 10100 1096152 java.lang.Class 3: 42595 1022280 java.lang.String 4: 27743 887776 java.util.concurrent.ConcurrentHashMap$Node 5: 10598 599128 [Ljava.lang.Object; 6: 26119 417904 java.lang.Object

JDK Flight Recorder (jfr)

JDK Flight Recorder — это механизм для трассировки во время выполнения, который позволяет записывать различные события активности, происходящие в JVM, и соотносить их с активностью приложения.
Возможна трассировка всего, включая JIT-оптимизации, сборки мусора, точек сохранения и даже пользовательских событий.

Инструмент jfr позволяет читать и отображать файлы JDK Flight Recorder с помощью команд print , summary и metadata .
Выдачу результатов можно представить в удобочитаемом текстовом формате или JSON/XML ( —json, —xml ).

  • print представляет весь журнал событий
  • metadata показывает, какие события были записаны (классы событий)
  • summary показывает в виде гистограммы, какие события были записаны, как часто
jfr summary /tmp/test.jfr Version: 2.0 Chunks: 1 Start: 2020-06-21 12:06:38 (UTC) Duration: 7 s Event Type Count Size (bytes) =========================================================== jdk.ModuleExport 2536 37850 jdk.ClassLoaderStatistics 1198 35746 jdk.NativeLibrary 506 45404 jdk.SystemProcess 490 53485 jdk.JavaMonitorWait 312 8736 jdk.NativeMethodSample 273 4095 jdk.ModuleRequire 184 2578 jdk.ThreadAllocationStatistics 96 1462 jdk.ThreadSleep 65 1237 jdk.ThreadPark 53 2012 jdk.InitialEnvironmentVariable 40 2432 jdk.InitialSystemProperty 20 16392 jdk.ThreadCPULoad 17 357

Чтобы ограничить количество информации, категории можно фильтровать с помощью флага —categories «GC,JVM,Java*» , а события с помощью флага —events CPULoad,GarbageCollection или —events «jdk.*» .
К сожалению, это невозможно с помощью summary или metadata , только с помощью print .

Лучшим инструментом для оценки записей JFR, конечно же, является JDK Mission Control (JMC), который был выпущен как OpenSource, начиная с Java 11, а также предлагается другими поставщиками, такими как Azul.

jdeprscan

Поскольку в последние годы некоторые компоненты были исключены из JDK (discontinued), jdeprscan позволяет сканировать классы, каталоги или файлы jar для определения использования этих API.

jdeprscan --release 11 testcontainers/testcontainers/1.9.1/testcontainers-1.9.1.jar 2>&1 | grep -v 'error: cannot ' Jar file testcontainers/testcontainers/1.9.1/testcontainers-1.9.1.jar: class org/testcontainers/shaded/org/apache/commons/lang/reflect/FieldUtils uses deprecated method java/lang/reflect/AccessibleObject::isAccessible()Z class org/testcontainers/shaded/org/apache/commons/lang/reflect/MemberUtils uses deprecated method java/lang/reflect/AccessibleObject::isAccessible()Z class org/testcontainers/shaded/org/apache/commons/io/input/ClassLoaderObjectInputStream uses deprecated method java/lang/reflect/Proxy::getProxyClass(Ljava/lang/Class

С помощью jdeprscan —list —release 11 вы можете перечислить API, которые объявлены устаревшими (deprecated) в этом релизе.

jdeprscan --release 11 --list | cut -d' ' -f 3- | cut -d. -f1-3 | sort | uniq -c | sort -nr | head -10 132 40 java.rmi.server 34 java.awt.Component 25 javax.swing.text 25 javax.swing.plaf 20 javax.management.monitor 18 java.util.Date 13 java.awt.List 9 javax.swing.JComponent 8 java.util.concurrent

Другие инструменты

Есть, конечно, еще много важных инструментов для работы с JVM, от async-profiler и jol (Java Object Layout) до графических программ для разбора и отображения журналов GC (https://gceasy.io), записей JFR (jmc) или дампов кучи (jvisualvm, Eclipse-MAT).

Другие инструменты, такие как отладчик Java jdb , не так удобны, как возможности IDE для удобной отладки как на локальных, так и на удаленных компьютерах.

Заключение

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

Их определенно стоит попробовать и узнать о них больше.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *