Strumento da riga di comando per trovare la dimensione dell'heap Java e la memoria utilizzata (Linux)?


171

Esiste uno strumento da riga di comando (Linux) per controllare la dimensione dell'heap (e la memoria utilizzata) di un'applicazione Java?

Ho provato tramite jmap. Ma dà informazioni. su aree di memoria interna come Eden / PermGen ecc., che non mi è utile.

Sto cercando qualcosa come:

  • Memoria massima: 1 GB
  • Memoria minima: 256 MB
  • Memoria heap: 700 MB
  • Memoria utilizzata: 460 MB

È tutto. So di poterlo vedere in JConsole ecc., Ma ho bisogno di uno strumento da riga di comando (non posso abilitare JMX ecc.)

Conosci qualche strumento / comando del genere?

Risposte:


150

Ogni processo Java ha un pid, che devi prima trovare con il jpscomando.

Una volta ottenuto il pid, è possibile utilizzare jstat -gc [insert-pid-here]per trovare statistiche sul comportamento dell'heap raccolto immondizia.

  • jstat -gccapacity [insert-pid-here] presenterà informazioni sulla generazione del pool di memoria e le capacità di spazio.

  • jstat -gcutil [insert-pid-here]presenterà l'utilizzo di ogni generazione come percentuale della sua capacità. Utile per avere una visione d'insieme dell'uso.

Consulta i documenti jstat sul sito di Oracle.


11
Esiste una raccomandazione quali opzioni jstatsi dovrebbero usare per verificare solo l'utilizzo della memoria complessiva di una JVM? Supponiamo che avvii la JVM con Xms=4ge Xmx=4gdesideri vedere quanta memoria sia già utilizzata?
basZero,

1
"jstat -gcutil <pid> 250 N" è stato molto utile per prelevare N campioni con intervalli di 250 ms e visualizzare l'output come percentuale per gli spazi corrispondenti. Grazie.
Kerem,

3
Da segnalare citazione da jstatOracle Java 8 manuale di pagina : This command is experimental and unsupported.
patryk.beza,

1
awk 'print {$3+$4+$6+$8}'può stampare un uso sintetico delle colonne jstat di Java 8
cybersoft,

Ho avuto problemi con le altre risposte, ma una base ps -ef | grep javami ha mostrato l'argm vm, che nel mio caso includeva il valore -Xmx, che era tutto ciò di cui avevo bisogno.
xdhmoore,

66

jvmtop è uno strumento da riga di comando che fornisce una vista dal vivo su diverse metriche, incluso heap.

Esempio di output della modalità panoramica 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

È davvero un ottimo strumento, una specie di htop ma con metriche di jstat. Grazie per il suggerimento, @MRalwasser.
oski86,

65

Questo comando mostra le dimensioni dell'heap configurate in byte.

java -XX:+PrintFlagsFinal -version | grep HeapSize

Funziona su Amazon AMI anche su EC2.


27
Questo non risponde alla domanda, che chiede specificamente come verificare l'utilizzo dell'heap di un processo. Il comando qui elenca le impostazioni predefinite JVM in tutti i processi.
Madbreaks,

10
Tuttavia, è una risposta molto utile per me venire a questa pagina tramite la ricerca di Google su come trovare la dimensione heap globale.
Johan

@jumping_monkey non indiretto, errato. Se quello che stai dicendo è vero, la risposta dovrebbe essere modificata o dovresti sentirti libero di aggiungere una nuova risposta.
Madbreaks,

43

Prova questo ha funzionato in Ubuntu e RedHat:

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

Per Windows:

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

Per Mac

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

L'output di tutti questi comandi è simile all'output seguente:

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)

Per trovare la dimensione in MB, dividere il valore con (1024 * 1024).


Come trovare l'utilizzo della memoria separato da heap, permsize, ... di specifici processi java da pid?
Gary Gauh,

3
@GaryGauh Questa è la dimensione heap predefinita. Per trovare l'uso dell'applicazione in esecuzione, è necessario farlo all'interno del codice oppure è possibile utilizzare jconsole. Questo è quello che so che dovrebbero esserci anche molti altri modi.
Padippist

2
Utilizzare jstat -gc <vmid>per l'esecuzione di applicazioni.
Micha Wiedenmann,

28

Senza usare JMX, che è quello che la maggior parte degli strumenti usa, tutto ciò che puoi fare è usare

jps -lvm

e dedurre che le impostazioni saranno dalle opzioni della riga di comando.

Non puoi ottenere informazioni dinamiche senza JMX per impostazione predefinita, ma puoi scrivere il tuo servizio per farlo.

A proposito: preferisco usare VisualVM piuttosto che JConsole.


25

Esiste uno strumento da riga di comando con un aspetto visivo: jvm-mon . È uno strumento di monitoraggio JVM per la riga di comando che disaplys:

  • heap utilizzo, dimensioni e max
  • processi jvm
  • utilizzo di cpu e GC
  • discussioni in alto

Le metriche e i grafici si aggiornano mentre lo strumento è aperto.

Campione: jvm-mon


1
Solo per notare che jvm-mon funziona solo per Java8
tmanolatos,

1
^ C'è una nuova versione che ora supporta anche Java 11.
Andrejs

11

In ritardo alla festa, ma una soluzione molto semplice è usare lo script jpsstat.sh. Fornisce una semplice memoria corrente attiva , memoria massima e dettagli sull'uso della CPU .

  • Vai al progetto GitHub e scarica il file jpsstat.sh
  • Fare clic con il tasto destro su jpsstat.sh e andare alla scheda permessi e renderlo eseguibile
  • Ora esegui lo script usando il seguente comando ./jpsstat.sh

Ecco l'output di esempio dello script -

=====  ======  =======  =======  =====
 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

sembra non funzionare fuori dagli schemi su un SUSE Linux (riga 38: dichiarare: -A: opzione non valida)
Chris

sembra che si ottenga un errore nella dichiarazione di array associativo che richiede bash> = 4. Inoltre, un altro problema potrebbe essere dovuto all'esecuzione dello script come "sh jpsstat.sh". In tal caso, prova a eseguire lo script come "./jpsstat.sh".
amarjeet e il

9

Nel mio caso avevo bisogno di controllare le bandiere all'interno di un contenitore docker che non aveva la maggior parte delle utilità di base (ps, pstree ...)

Usando jpsho ottenuto il PID della JVM in esecuzione (nel mio caso 1) e poi con jcmd 1 VM.flagsho ottenuto i flag dalla JVM in esecuzione.

Dipende da quali comandi hai a disposizione, ma questo potrebbe aiutare qualcuno. :)


8

Da Java8 e versioni successive , è possibile utilizzare il comando seguente:

jcmd JAVA_PROCESS_IDGC.heap_info

È possibile fare riferimento alla somma della memoria totale e utilizzata dall'output.

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

Per maggiori dettagli sul comando jcmd, visitare il link: https://docs.oracle.com/javase/8/docs/technotes/guides/troubleshoot/tooldescr006.html


1
Devi correggere il tuo commento. GC.heap_info è disponibile in Java 9 e versioni successive. Non è disponibile in Java 8. Vedi un'altra discussione qui: stackoverflow.com/questions/41891127/…
Pavel Molchanov

@PavelMolchanov Sono in grado di utilizzare il comando in jdk1.8.0_172. /Library/Java/JavaVirtualMachines/jdk1.8.0_172.jdk/Contents/Home/bin/jcmd 98270 GC.heap_info. Per favore, se puoi, aggiungi le informazioni al thread di riferimento e non ho abbastanza reputazione per ora per aggiungere un commento lì.
vaibhav gupta,

Usi il Mac? Usi Oracle JDK? Non so come possa essere disponibile nel tuo jdk1.8.0_172, Oracle ha documentato questa funzione solo in Java 9 e versioni successive : docs.oracle.com/javase/9/tools/jcmd.htm . Non è nella documentazione di Oracle JDK per Java 8. Non è menzionato nel link che hai dato in fondo: docs.oracle.com/javase/8/docs/technotes/guides/troubleshoot/…
Pavel Molchanov

Un'altra domanda. Controllare la versione JDK che esegue il processo 98270 nell'esempio. jcmd ottiene i comandi disponibili da JVM del processo (nel tuo caso 98270). Se il processo 98270 viene eseguito con JDK diverso (JDK 9 o successivo), vedrai il comando GC.heap_info disponibile anche in JCMD stesso da Java 8. I comandi disponibili potrebbero essere diversi per processi diversi. Per ottenere i comandi disponibili, eseguire: jcmp <PID> aiuto.
Pavel Molchanov,

1
FWIW, GC.heap_infoè sicuramente disponibile anche in OpenJDK 8. Forse solo nelle versioni recenti? Sto usando questo: 8u191-b12-2ubuntu0.18.04.1
Per Lundberg,

7

Qualsiasi approccio dovrebbe darti approssimativamente lo stesso numero. È sempre una buona idea assegnare l'heap utilizzando -X..m -X..xper tutte le generazioni. Puoi quindi garantire e fare anche ps per vedere quali parametri sono stati passati e quindi utilizzati.

Per gli utilizzi effettivi della memoria, è possibile confrontare approssimativamente il confronto VIRT (allocato e condiviso) e RES (effettivamente utilizzato) con i valori jstat:

Per Java 8, vedere jstat per questi valori in realtà significano. Supponendo di eseguire una classe semplice senza mmap o elaborazione di file.

$ 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

Max :

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

(approssimativamente vicino e sotto alla memoria VIRT)

Max (Min, usato):

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

(approssimativamente vicino alla memoria RES)

"Non citarmi su questo" ma VIRT mem è approssimativamente vicino o superiore alla memoria Max allocata ma fintanto che la memoria utilizzata è libera / disponibile nella memoria fisica, JVM non genera eccezioni di memoria. In effetti, la memoria massima non viene nemmeno verificata rispetto alla memoria fisica all'avvio di JVM anche con swap disattivato sul sistema operativo. Una spiegazione migliore di quale memoria virtuale è realmente utilizzata da un processo Java è discussa qui .


4

Per prima cosa ottieni l'id del processo, il primo numero dal processo elencato, da uno dei seguenti: (o usa semplicemente ps aux | grep java, se lo preferisci)

jps -lvm

Quindi utilizzare l'ID processo qui:

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

2

L'uso del topcomando è il modo più semplice per controllare l'utilizzo della memoria del programma. REScolonna mostra la memoria fisica reale occupata da un processo.

Per il mio caso, avevo un file da 10 g letto in java e ogni volta che uscivo dall'eccezione di Memoria. Ciò è accaduto quando il valore nella REScolonna ha raggiunto il valore impostato -Xmxnell'opzione. Quindi aumentando la memoria usando l' -Xmxopzione tutto è andato bene.


3
Il comando top sta mostrando quanto OS viene dato alla JVM. questi ragazzi ci chiedono come possiamo vedere l'utilizzo dello spazio heap all'interno di JVM. JVM utilizza 10g non significa che lo spazio heap reale è pieno di dati 10g, perché jvm non restituisce quasi mai memoria dall'OSH al sistema operativo fino a quando non si interrompe il processo.
linehrr,

2

In termini di dimensioni dell'heap Java, in Linux è possibile utilizzare

ps aux | grep java

o

ps -ef | grep java

e cerca -Xms, -Xmx per scoprire la dimensione heap iniziale e massima specificata.

Tuttavia, se -Xms o -Xmx è assente per il processo Java che ti interessa, significa che il tuo processo Java utilizza le dimensioni heap predefinite. È possibile utilizzare il comando seguente per scoprire le dimensioni predefinite.

java -XX:+PrintFlagsFinal -version | grep HeapSize

o un particolare jvm, ad esempio,

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

e cerca InitialHeapSize e MaxHeapSize, che è in byte.


1

Se si utilizza jrockit, provare lo strumento da riga di comando jrcmd. Per esempio:

$ 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)

Per altri comandi, come heap_diagnostics, usa "jrcmd help" per elencarli.

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 )

Esempio O / P del comando sopra

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).

Maggiori dettagli a riguardo su http://docs.oracle.com/javase/1.5.0/docs/tooldocs/share/jstat.html


1

Finora non esiste uno strumento simile per stampare la memoria heap nel formato richiesto. L'unico e unico modo per stampare è scrivere un programma java con l'aiuto di 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);
}

}

riferimento: https://viralpatel.net/blogs/getting-jvm-heap-size-used-memory-total-memory-using-java-runtime/


questo è sbagliato. jmap -heap <pid> fornisce queste informazioni
vsingh

0

Trova dall'alto l'id del processo del tuo processo webapp / java. Utilizzare jmap heap per ottenere l'allocazione dell'heap. Ho provato questo su AWS-Ec2 per beanstalk elastico

Nell'immagine puoi vedere un heap massimo di 3 GB per l'applicazione

inserisci qui la descrizione dell'immagine

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.