Інструмент командного рядка для пошуку розміру масиву Java та пам'яті, що використовується (Linux)?


171

Чи є інструмент командного рядка (Linux) для перевірки розміру купи (і використовуваної пам'яті) програми Java?

Я спробував через jmap. Але це дає інформацію. про такі області внутрішньої пам'яті, як Eden / PermGen тощо, що мені не корисно.

Я шукаю щось на зразок:

  • Максимальна пам'ять: 1 Гб
  • Мінімальна пам'ять: 256 Мб
  • Пам'ять купи: 700 Мб
  • Пам'ять, що використовується: 460 Мб

Це все. Я знаю, що я бачу це в JConsole і т. Д., Але мені потрібен інструмент командного рядка (не вмикаю JMX тощо)

Чи знаєте ви такий інструмент / команду?

Відповіді:


149

Кожен процес Java має a pid, який спочатку потрібно знайти за допомогою jpsкоманди.

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

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

  • jstat -gcutil [insert-pid-here]представить використання кожного покоління у відсотках від його потужності. Корисно для огляду використання.

Дивіться документи jstat на сайті Oracle.


11
Чи є рекомендація, які параметри jstatслід використовувати, щоб перевірити лише загальне використання пам'яті JVM? Скажімо, ви починаєте JVM з Xms=4gі Xmx=4gхочете побачити, скільки пам'яті на це вже використовується?
basZero

1
"jstat -gcutil <pid> 250 N" було дуже корисно брати N зразків з інтервалом 250ms і відображати вихід у відсотках для відповідних пробілів. Дякую.
Керем

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 - це інструмент командного рядка, який забезпечує перегляд у прямому ефірі за кількома показниками, включаючи купу.

Приклад виведення режиму огляду VM:

 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

Це дійсно чудовий інструмент, свого роду htop, але з показниками jstat. Дякую за пропозицію, @MRalwasser.
oski86

65

Ця команда показує налаштовані розміри купи в байтах.

java -XX:+PrintFlagsFinal -version | grep HeapSize

Він також працює на Amazon AMI на EC2.


26
Це не дає відповіді на запитання, яке конкретно задає питання, як перевірити використання купі процесу. Команда тут перераховує стандартні параметри JVM у всіх процесах.
Madbreaks

10
Тим не менше, це дуже корисна відповідь для мене, що заходить на цю сторінку за допомогою google пошуку про те, як знайти глобальний розмір купи.
Йоган

@jumping_monkey не непрямий, неправильний. Якщо те, що ви говорите, відповідає дійсності, відповідь слід відредагувати або не соромтеся додати нову відповідь.
Madbreaks

42

Спробуйте це працювало в 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).


Як знайти використання пам'яті, відокремленої купою, permsize, ... певного Java-процесу за допомогою pid?
Гарі Гау

3
@GaryGauh Це розмір купи за замовчуванням. Щоб знайти використання запущеної програми, слід зробити це в коді або скористатися jconsole. Це те, що я знаю, що існує також багато інших способів.
падіппіст

2
Використовувати jstat -gc <vmid>для запуску програм.
Micha Wiedenmann

27

Без використання JMX, для чого використовується більшість інструментів, все, що ви можете зробити - це використовувати

jps -lvm

і зробити висновок, що налаштування будуть з параметрів командного рядка.

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

BTW: Я вважаю за краще використовувати VisualVM, а не JConsole.


25

Існує інструмент командного рядка з візуальним аспектом - jvm-mon . Це інструмент моніторингу JVM для командного рядка, який не відповідає:

  • використання купи, розмір і макс
  • jvm процеси
  • використання процесора та GC
  • верхні нитки

Показники та діаграми оновлюються, коли інструмент відкритий.

Зразок: jvm-пн


1
Зауважимо лише, що jvm-mon працює лише для Java8
tmanolatos

1
^ Є нова версія, яка тепер також підтримує Java 11.
Андрейс

11

Пізно на вечірці, але дуже простим рішенням є використання сценарію jpsstat.sh. Він забезпечує просту живу поточну пам'ять , максимум пам'яті та деталі використання процесора

  • Перейдіть на проект 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

здається, не виходить із скриньки на SUSE Linux (рядок 38: оголосити: -A: недійсний варіант)
Кріс,

звучить так, що ви отримуєте помилку в оголошенні асоціативного масиву, для якого потрібно bash> = 4. Також інша проблема може бути пов'язана із запуском сценарію як "sh jpsstat.sh". Якщо так, спробуйте запустити скрипт як "./jpsstat.sh".
amarjeetAnand

9

У моєму випадку мені потрібно було перевірити прапори всередині контейнера docker, у якому не було більшості основних утиліт (ps, pstree ...)

Використовуючи, jpsя отримав PID запущеного JVM (у моєму випадку 1), а потім jcmd 1 VM.flagsотримав прапори запущеного JVM.

Це залежить від того, які команди у вас є, але це може комусь допомогти. :)


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. Будь ласка, якщо ви можете, додайте інформацію до згадуваної теми, а я не маю достатньо репутації на даний момент, щоб додати коментар.
vaibhav gupta

Ви використовуєте 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

(приблизно в пам’яті з ВДЕ)

"Не цитуйте мене з цього приводу", але пам'ять VIRT приблизно близька або більше, ніж виділена максимальна пам'ять, але поки пам'ять, що використовується, є вільною / доступною у фізичній пам'яті, JVM не викидає пам'ять виключення. Насправді, максимальна пам'ять навіть не перевіряється фізичною пам'яттю при запуску JVM навіть при відключенні в ОС. Найкраще пояснення того , що Віртуальна пам'ять дійсно використовується процесом Java обговорюється тут .


4

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

jps -lvm

Потім використовуйте тут ідентифікатор процесу:

jmap -heap $MY_PID 2>/dev/null | sed -ne '/Heap Configuration/,$p';
jmap -permstat $MY_PID

2

Використання topкоманди - це найпростіший спосіб перевірити використання пам'яті програми. RESстовпчик показує реальну фізичну пам'ять, яку займає процес.

У моєму випадку я мав читати файл у форматі 10 г у Java, і кожен раз, коли я виходив із виняткуOfMemory. Це сталося, коли значення в RESстовпці досягло значення, встановленого в -Xmxопції. Потім, збільшивши пам'ять за допомогою -Xmxопції, все пішло нормально.


3
команда вгорі показує, скільки ОС задано JVM. хлопці запитують, як ми можемо бачити використання місця в купі JVM. JVM використовує 10 г, це не означає, що реальний простір купи заповнений 10 г даних, оскільки 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


1

Досі не існує такого інструменту для друку пам’яті купи у форматі, як ви вимагали . Єдиний і єдиний спосіб друку - це написання програми java за допомогою класу Runtime ,

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

Знайдіть ідентифікатор процесу вашого веб-сайту / java-процесу зверху. Використовуйте jmap heap, щоб отримати розподіл купи. Я перевірив це на AWS-Ec2 для пружної підкладки

Ви можете бачити на зображенні нижче максимум 3 ГБ для програми

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.