Инструмент командной строки для определения размера кучи Java и используемой памяти (Linux)?

171

Существует ли инструмент командной строки (Linux) для проверки размера кучи (и используемой памяти) приложения Java?

Я пробовал через jmap. Но это дает информацию. о внутренних областях памяти, таких как Eden / PermGen и т. д., что мне не полезно.

Я ищу что-то вроде:

  • Макс. Память: 1 ГБ
  • Минимальная память: 256 МБ
  • Память кучи: 700 МБ
  • Используемая память: 460 МБ

Вот и все. Я знаю, что вижу это в JConsole и т. Д., Но мне нужен инструмент командной строки (не могу включить JMX и т. Д.)

Вы знаете какой-нибудь такой инструмент / команду?

Джаспер
источник

Ответы:

150

У каждого Java-процесса есть pid, который вы сначала должны найти с помощью jpsкоманды.

Получив pid, вы можете использовать jstat -gc [insert-pid-here]статистику поведения кучи для сбора мусора.

  • jstat -gccapacity [insert-pid-here] представит информацию о создании пула памяти и возможностях пространства.

  • jstat -gcutil [insert-pid-here]представит использование каждого поколения в процентах от его мощности. Полезно, чтобы получить краткий обзор использования.

Смотрите документацию jstat на сайте Oracle.

farmer1992
источник
11
Есть ли рекомендации, какие варианты jstatследует использовать, чтобы проверить только общее использование памяти JVM? Допустим, вы запускаете JVM Xms=4gи Xmx=4gхотите посмотреть, сколько памяти уже используется?
BasZero
1
«jstat -gcutil <pid> 250 N» было очень полезно взять N выборок с интервалами 250 мс и отобразить выходные данные в процентах для соответствующих пробелов. Спасибо.
Керем
3
Стоит отметить , цитату из jstatOracle Java 8 ручной страницы : This command is experimental and unsupported.
patryk.beza
1
awk 'print {$3+$4+$6+$8}'может печатать итоговое использование в столбцах
jstat
У меня были проблемы с другими ответами, но основной ps -ef | grep javaпоказал мне аргументы vm, которые в моем случае включали значение -Xmx, и это было все, что мне было нужно.
xdhmoore
66

jvmtop - это инструмент командной строки, который обеспечивает просмотр в реальном времени по нескольким показателям, включая кучу.

Пример вывода режима обзора виртуальной машины:

 JvmTop 0.3 alpha (expect bugs)  amd64  8 cpus, Linux 2.6.32-27, load avg 0.12
 http://code.google.com/p/jvmtop

  PID MAIN-CLASS      HPCUR HPMAX NHCUR NHMAX    CPU     GC    VM USERNAME   #T DL
 3370 rapperSimpleApp  165m  455m  109m  176m  0.12%  0.00% S6U37 web        21
11272 ver.resin.Resin [ERROR: Could not attach to VM]
27338 WatchdogManager   11m   28m   23m  130m  0.00%  0.00% S6U37 web        31
19187 m.jvmtop.JvmTop   20m 3544m   13m  130m  0.93%  0.47% S6U37 web        20
16733 artup.Bootstrap  159m  455m  166m  304m  0.12%  0.00% S6U37 web        46
MRalwasser
источник
Это действительно отличный инструмент, вроде htop, но с метриками из jstat. Спасибо за предложение, @MRalwasser.
oski86
65

Эта команда показывает настроенные размеры кучи в байтах.

java -XX:+PrintFlagsFinal -version | grep HeapSize

Он работает на Amazon AMI на EC2.

Атма
источник
27
Это не отвечает на вопрос, который конкретно спрашивает, как проверить использование кучи процесса. Команда здесь перечисляет значения по умолчанию JVM для всех процессов.
Madbreaks
10
Тем не менее, это очень полезный ответ для меня, когда я захожу на эту страницу через поиск в Google о том, как найти размер глобальной кучи.
Йохан
@jumping_monkey не косвенный, неверный. Если то, что вы говорите, правда, ответ должен быть отредактирован, или вы можете свободно добавлять новый ответ.
Madbreaks
43

Попробуйте это, это работало в Ubuntu и RedHat:

java -XX:+PrintFlagsFinal -version | grep -iE 'HeapSize|PermSize|ThreadStackSize'

Для Windows:

java -XX:+PrintFlagsFinal -version | findstr /i "HeapSize PermSize ThreadStackSize"

Для Mac

java -XX:+PrintFlagsFinal -version | grep -iE 'heapsize|permsize|threadstacksize'

Вывод всех этих команд похож на вывод ниже:

uintx InitialHeapSize                          := 20655360        {product}
uintx MaxHeapSize                              := 331350016       {product}
uintx PermSize                                  = 21757952        {pd product}
uintx MaxPermSize                               = 85983232        {pd product}
intx ThreadStackSize                           = 1024            {pd product}
java version "1.7.0_05"
Java(TM) SE Runtime Environment (build 1.7.0_05-b05)
Java HotSpot(TM) 64-Bit Server VM (build 23.1-b03, mixed mode)

Чтобы найти размер в МБ, разделите значение на (1024 * 1024).

padippist
источник
Как найти использование памяти, разделенное на кучу, permsize, ... конкретного процесса Java с помощью pid?
Гэри
3
@GaryGauh Это размер кучи по умолчанию. Чтобы найти использование запущенного приложения, вы должны сделать это в коде или вы можете использовать jconsole. Это то, что я знаю, должно быть много других способов.
падиппист
2
Используйте jstat -gc <vmid>для запуска приложений.
Миха Виденманн
28

Без использования JMX, который используется большинством инструментов, все, что вы можете сделать, это использовать

jps -lvm

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

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

Кстати: я предпочитаю использовать VisualVM, а не JConsole.

Питер Лори
источник
25

Существует инструмент командной строки с визуальным аспектом - jvm-mon . Это инструмент мониторинга JVM для командной строки, который отключается:

  • использование кучи, размер и макс
  • процессы JVM
  • использование процессора и GC
  • лучшие темы

Метрики и диаграммы обновляются, пока инструмент открыт.

Образец: пн-JVM

Андрейс
источник
1
Просто отметим, что jvm-mon работает только для Java8
tmanolatos
1
^ Есть новая версия, которая теперь также поддерживает Java 11.
Андрейс
11

Поздно вечером, но очень простое решение - использовать скрипт jpsstat.sh. Он обеспечивает простую текущую оперативную память , максимальную память и информацию об использовании процессора .

  • Goto проект GitHub и скачать jpsstat.sh файл
  • Щелкните правой кнопкой мыши на jpsstat.sh и перейдите к разрешениям. и сделайте ее исполняемой
  • Теперь запустите скрипт, используя следующую команду ./jpsstat.sh

Вот пример вывода скрипта -

=====  ======  =======  =======  =====
 PID    Name   CurHeap  MaxHeap  %_CPU
=====  ======  =======  =======  =====
2777   Test3      1.26     1.26    5.8
2582   Test1      2.52     2.52    8.3
2562   Test2      2.52     2.52    6.4
amarjeetAnand
источник
похоже, не работает из коробки на SUSE Linux (строка 38: объявлять: -A: недопустимая опция)
Крис
Звучит так, как будто вы получили ошибку в объявлении ассоциативного массива, для которого требуется bash> = 4. Также другая проблема может быть связана с запуском скрипта как «sh jpsstat.sh». Если это так, попробуйте запустить скрипт как «./jpsstat.sh».
amarjeetAnand
9

В моем случае мне нужно было проверить флаги внутри контейнера докера, в котором не было большинства основных утилит (ps, pstree ...)

Используя, jpsя получил PID работающей JVM (в моем случае 1), а затем jcmd 1 VM.flagsполучил флаги от работающей JVM.

Это зависит от того, какие команды у вас есть, но это может кому-то помочь. :)

froblesmartin
источник
8

От Java8 и выше , вы можете использовать команду:

jcmd JAVA_PROCESS_IDGC.heap_info

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

Sample Command And Output: jcmd 9758 GC.heap_info

PSYoungGen  total 1579520K, used 487543K [0x0000000751d80000, 0x00000007c0000000, 0x00000007c0000000)
  eden space 1354240K, 36% used [0x0000000751d80000,0x000000076f99dc40,0x00000007a4800000)
  from space 225280K, 0% used [0x00000007b2400000,0x00000007b2400000,0x00000007c0000000)
  to   space 225280K, 0% used [0x00000007a4800000,0x00000007a4800000,0x00000007b2400000)
ParOldGen       total 3610112K, used 0K [0x0000000675800000, 0x0000000751d80000, 0x0000000751d80000)
  object space 3610112K, 0% used [0x0000000675800000,0x0000000675800000,0x0000000751d80000)
Metaspace       used 16292K, capacity 16582K, committed 16896K, reserved 1064960K
  class space    used 1823K, capacity 1936K, committed 2048K, reserved 1048576K

Для получения дополнительной информации о команде jcmd посетите ссылку: https://docs.oracle.com/javase/8/docs/technotes/guides/troubleshoot/tooldescr006.html.

Вайбхав Гупта
источник
1
Вы должны исправить свой комментарий. GC.heap_info доступен в Java 9 и выше. Это не доступно в Java 8. Смотрите другой поток здесь: stackoverflow.com/questions/41891127/…
Павел Молчанов
@PavelMolchanov Я могу использовать команду в jdk1.8.0_172. /Library/Java/JavaVirtualMachines/jdk1.8.0_172.jdk/Contents/Home/bin/jcmd 98270 GC.heap_info. Пожалуйста, если можете, добавьте информацию в упомянутую ветку, так как на данный момент у меня недостаточно репутации, чтобы добавить туда комментарий.
Вайбхав Гупта
Вы используете Mac? Вы используете Oracle JDK? Я не знаю, как это может быть доступно в вашем jdk1.8.0_172, Oracle задокументировал эту функцию только в Java 9 и выше: docs.oracle.com/javase/9/tools/jcmd.htm . Этого нет в документации Oracle JDK для Java 8. Это не упоминается в приведенной ниже ссылке: docs.oracle.com/javase/8/docs/technotes/guides/troubleshoot/…
Павел Молчанов,
Еще один вопрос. Пожалуйста, проверьте версию JDK, которая запускает процесс 98270 в вашем примере. jcmd получает доступные команды от JVM процесса (в вашем случае 98270). Если процесс 98270 выполняется с другим JDK (JDK 9 или выше), вы увидите, что команда GC.heap_info доступна даже в самом JCMD из Java 8. Доступные команды могут отличаться для разных процессов. Чтобы получить доступные команды, выполните: jcmp <PID> help.
Павел Молчанов
1
FWIW, GC.heap_infoбезусловно, также доступен в OpenJDK 8. Может быть, только в последних версиях? Я использую это: 8u191-b12-2ubuntu0.18.04.1
Per Lundberg
7

Любой подход должен дать вам примерно одинаковое число. Всегда полезно выделять кучу -X..m -X..xдля всех поколений. Затем вы можете гарантировать, а также сделать ps, чтобы увидеть, какие параметры были переданы и, следовательно, используются.

Для фактического использования памяти вы также можете приблизительно сравнить VIRT (выделенный и совместно используемый) и RES (фактически используемый), а также значения jstat:

Для Java 8 см. Jstat для этих значений на самом деле. Предполагая, что вы запускаете простой класс без mmap или обработки файлов.

$ jstat -gccapacity 32277
 NGCMN    NGCMX     NGC     S0C   S1C       EC      OGCMN      OGCMX       OGC         OC       MCMN     MCMX      MC     CCSMN    CCSMX     CCSC    YGC    FGC
215040.0 3433472.0  73728.0  512.0  512.0  67072.0   430080.0  6867968.0   392704.0   392704.0      0.0 1083392.0  39680.0      0.0 1048576.0   4864.0   7225     2
$ jstat -gcutil 32277
  S0     S1     E      O      M     CCS    YGC     YGCT    FGC    FGCT     GCT
  6.25   0.00   7.96  18.21  98.01  95.29   7228   30.859     2    0.173   31.032

Макс :

     NGCMX + S0C + S1C + EC    + OGCMX   + MCMX    + CCSMX
   3433472 + 512 + 512 + 67072 + 6867968 + 1083392 + 1048576 = 12 GB

(примерно близко и ниже к VIRT памяти)

Макс (Мин, Используется):

215040 + 512 + 512 + 67072 + 430080  + 39680    +  4864  = ~ 1GB

(примерно близко к памяти RES)

«Не цитируйте меня по этому поводу», но VIRT mem примерно равна или превышает максимально выделенную память, но пока используемая память свободна / доступна в физической памяти, JVM не выдает исключение памяти. Фактически, максимальный объем памяти даже не проверяется на предмет физической памяти при запуске JVM, даже если в ОС он выключен. Лучшее объяснение того, что Виртуальная память действительно использовала процесс Java, обсуждается здесь .

kisna
источник
4

Сначала получите идентификатор процесса, первое число из перечисленного процесса, из одного из следующих: (или просто используйте ps aux | grep java, если хотите)

jps -lvm

Затем используйте идентификатор процесса здесь:

jmap -heap $MY_PID 2>/dev/null | sed -ne '/Heap Configuration/,$p';
jmap -permstat $MY_PID
sjas
источник
2

Использование topкоманды - это самый простой способ проверить использование памяти программой. RESстолбец показывает реальную физическую память, занятую процессом.

Для моего случая у меня был файл 10g, прочитанный в Java, и каждый раз, когда я получал исключение OutOfMemory. Это произошло, когда значение в RESстолбце достигло значения, заданного -Xmxпараметром. Затем, увеличив память с помощью -Xmxопции, все прошло нормально.

М. Машай
источник
3
Команда top показывает, сколько ОС отдано JVM. этот парень спрашивает, как мы можем увидеть использование пространства кучи внутри JVM. Использование JVM 10g не означает, что реальное пространство кучи заполнено данными 10g, потому что jvm почти никогда не возвращает память обратно в ОС из кучи, пока вы не завершите процесс.
linehrr
2

С точки зрения размера кучи Java, в Linux вы можете использовать

ps aux | grep java

или

ps -ef | grep java

и найдите -Xms, -Xmx, чтобы узнать начальный и максимальный указанный размер кучи.

Однако, если -Xms или -Xmx отсутствуют для интересующего вас Java-процесса, это означает, что ваш Java-процесс использует размеры кучи по умолчанию. Вы можете использовать следующую команду, чтобы узнать размеры по умолчанию.

java -XX:+PrintFlagsFinal -version | grep HeapSize

или конкретный JVM, например,

/path/to/jdk1.8.0_102/bin/java -XX:+PrintFlagsFinal -version | grep HeapSize

и найдите InitialHeapSize и MaxHeapSize, которые находятся в байтах.

Юйцы
источник
1

Если вы используете jrockit, попробуйте инструмент командной строки jrcmd. Например:

$ jrcmd 5127 print_memusage
5127:
Total mapped                  1074596KB           (reserved=3728KB)
-              Java heap       786432KB           (reserved=0KB)
-              GC tables        26316KB          
-          Thread stacks        13452KB           (#threads=34)
-          Compiled code         9856KB           (used=9761KB)
-               Internal          840KB          
-                     OS        15036KB          
-                  Other       146632KB          
-        Java class data        75008KB           (malloced=74861KB #103221 in 18709 classes)
- Native memory tracking         1024KB           (malloced=102KB #8)

Для получения дополнительных команд, таких как heap_diagnostics, используйте «jrcmd help» для их перечисления.

https://blogs.oracle.com/jrockit/entry/why_is_my_jvm_process_larger_t

гость
источник
1
jstat -gccapacity javapid  (ex. stat -gccapacity 28745)
jstat -gccapacity javapid gaps frames (ex.  stat -gccapacity 28745 550 10 )

Пример O / P вышеуказанной команды

NGCMN    NGCMX     NGC     S0C  
87040.0 1397760.0 1327616.0 107520.0 

NGCMN   Minimum new generation capacity (KB).
NGCMX   Maximum new generation capacity (KB).
NGC Current new generation capacity (KB).

Получить более подробную информацию об этом на http://docs.oracle.com/javase/1.5.0/docs/tooldocs/share/jstat.html

Pravin
источник
1

До сих пор не существует такого инструмента для печати памяти кучи в формате, который вы запрашивали . Единственный и единственный способ печати - это написать Java-программу с помощью Runtime Class ,

public class TestMemory {

public static void main(String [] args) {

    int MB = 1024*1024;

    //Getting the runtime reference from system
    Runtime runtime = Runtime.getRuntime();

    //Print used memory
    System.out.println("Used Memory:" 
        + (runtime.totalMemory() - runtime.freeMemory()) / MB);

    //Print free memory
    System.out.println("Free Memory:" 
        + runtime.freeMemory() / mb);

    //Print total available memory
    System.out.println("Total Memory:" + runtime.totalMemory() / MB);

    //Print Maximum available memory
    System.out.println("Max Memory:" + runtime.maxMemory() / MB);
}

}

ссылка: https://viralpatel.net/blogs/getting-jvm-heap-size-used-memory-total-memory-using-java-runtime/

Гаутам Прасат
источник
это не верно. jmap -heap <pid> дает эту информацию
vsingh
0

Найдите идентификатор процесса вашего webapp / java процесса сверху. Используйте кучу jmap, чтобы получить распределение кучи. Я тестировал это на AWS-Ec2 для эластичного бобового стебля

Вы можете увидеть на изображении ниже максимальную кучу 3 ГБ для приложения

введите описание изображения здесь

vsingh
источник