jcmd
Spesso, quando viene realizzata un’applicazione, sarebbe buona abitudine effettuare i necessari tests di performance , endurance e stress, in modo da rilevare eventuali punti critici o di miglioramento prima che l’applicazione , come si dice in gergo, venga messa in produzione. Nel caso di un’applicazione Java, occorre poter interagire con la JVM. Esistono diversi tolls e/o utility, uno di questi è jcmd che viene utilizzato per invocare comandi di diagnostica alla JVM (qui il riferimento ufficiale). Per scoprire i comandi che possiamo eseguire è sufficiente procedere come segue :
jcmd <pid> help
The following commands are available: VM.native_memory ManagementAgent.stop ManagementAgent.start_local ManagementAgent.start GC.rotate_log Thread.print GC.class_stats GC.class_histogram GC.heap_dump GC.run_finalization GC.run VM.uptime VM.flags VM.system_properties VM.command_line VM.version
In realtà, la disponibilità di un comando, piuttosto che un altro, dipende anche dalla JVM su cui operiamo (in questo caso si tratta di openjdk-1.8.0.77-0).
Un comando molto utile è il seguente :
jcmd <pid> VM.system_properties
ci permette di visionare tutte le system properties dell’applicativo che gira nella jvm
jcmd <pid> GC.heap_dump /tmp/test.hprof
permette di generare il dump dello heap che possiamo dare in pasto ad eventuali tools di analisi.
Infine, un comando che, secondo me, vale la pena tenere presente è
jcmd <pid> GC.run
Questo ci permette di forzare una System.gc() all”interno della JVM ed è, quindi, utilissimo per verificare che la memoria venga effettivamente liberata a seguito di un full gc. Ovviamente, per procedere, con tale osservazione occorre abilitare la nostra JVM a stampare l’andamento del gc.log. Questo si può banalemente attivare aggiungendo le seguenti options sulla linea di comando che istanzia la jvm :
-XX:+PrintGC -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -Xloggc:gc.log