Java >> Java Program >  >> JDK

jcmd:Ett JDK kommandoradsverktyg för att styra dem alla

Jag har refererat till det praktiska JDK-verktyget jcmd i flera inlägg tidigare, men fokuserar uteslutande på dess användbarhet här som jag tidigare har gjort för jps. Jcmd-verktyget introducerades med Oracles Java 7 och är särskilt användbart vid felsökning av problem med JVM-applikationer genom att använda det för att identifiera Java-processers ID (liknande jps), skaffa heapdumpar (liknande jmap), skaffa tråddumpar (liknande jstack) ), visa egenskaper för virtuella maskiner såsom systemegenskaper och kommandoradsflaggor (liknande jinfo), och skaffa statistik för skräpinsamling (liknande jstat). Verktyget jcmd har kallats "en schweizisk armékniv för att undersöka och lösa problem med din JVM-applikation" och en "dold pärla."

När du använder de flesta JDK kommandoradsverktyg (inklusive jcmd ), är det ofta viktigt att identifiera process-ID (pid) för Java-processen som vi vill använda kommandoradsverktyget för. Detta görs enkelt med jcmd genom att helt enkelt köra kommandot utan några argument som visas i nästa skärmbild.

Kör jcmd utan argument i exemplet ovan visar två Java-processer som körs (jcmd sig själv med en pid på 324 och en annan Java-process med en pid på 7268). Observera att även om jcmd fungerar mycket som jps när det gäller att lista Java-processer, jcmd listar mer information än jps gör utan argument -lm .

Kör jcmd -h visar hjälp och användningsinformation för jcmd som visas i nästa skärmbild.

Hjälpen förklarar, som precis visades, att jcmd "listar Java-processer" när "inga alternativ ges." Hjälpen anger också att detta är beteende liknande att köra jcmd -p , men jag tror att det betyder att köra jcmd utan alternativ motsvarar att köra jcmd -l , som visas i nästa skärmbild.

Som när jcmd kördes utan några alternativ, jcmd -l listar Java-processer och deras respektive pids. Pids är olika i det här exemplet eftersom det är en annan exekvering av jcmd och jag har en annan Java-process igång den här gången.

Kör jcmd -h visade relativt få alternativ. För att se hjälp om de många funktionerna som jcmd stöder måste man fråga jcmd vilka funktioner som stöds för en viss Java-process. Nästa skärmbild illustrerar detta. Jag kör först jcmd utan alternativ för att upptäcka pid av Java-processen av intresse (6320 i detta fall). Sedan kan jag köra jcmd 6320 help för att se vilka kommandon jcmd stödjer.

Den föregående skärmbilden visar kommandona jcmd stöder för den speciella Java VM som identifieras av pid. Specifikt står det "Följande kommandon är tillgängliga:" och listar dem sedan:

  • JFR.stop
  • JFR.start
  • JFR.dump
  • JFR.check
  • VM.native_memory
  • VM.check_commercial_features
  • VM.unlock_commercial_features
  • ManagementAgent.stop
  • ManagementAgent.start_local
  • ManagementAgent.start
  • GC.rotate_log
  • GC.class_stats
  • GC.class_histogram
  • GC.heap_dump
  • GC.run_finalization
  • GC.run
  • Thread.print
  • VM.uptime
  • VM.flags
  • VM.system_properties
  • VM.command_line
  • VM.version
  • hjälp

När jcmd <pid> help körs mot en pid för en annan Java VM-process, är det möjligt att få en annan lista över tillgängliga kommandon. Detta illustreras i nästa skärmbild när jcmd 1216 help exekveras mot den processen med pid på 1216.

Genom att jämföra de två senaste skärmbilderna blir det tydligt att jcmd stöder olika kommandon för olika Java VM-instanser. Det är därför de kommandon som stöds för en viss virtuell dator listas genom att ange pid i help kommando. Några av de kommandon som är tillgängliga mot den andra virtuella datorn (pid 1216 i det här fallet) som inte var listade för den ursprungligen kontrollerade virtuella datorn inkluderar följande:

  • VM.log
  • ManagementAgent.status
  • Compiler.directives_clear
  • Compiler.directives_remove
  • Compiler.directives_add
  • Compiler.directives_print
  • VM.print_touched_methods
  • Compiler.codecache
  • Compiler.codelist
  • Compiler.queue
  • VM.classloader_stats
  • JVMTI.data_dump
  • VM.stringtable
  • VM.symboltable
  • VM.class_hierarchy
  • GC.finalizer_info
  • GC.heap_info
  • VM.info
  • VM.dynlibs
  • VM.set_flag

Denna "hjälp" ger också råd, "För mer information om ett specifikt kommando använd 'hjälp '." Att göra detta illustreras i nästa skärmbild specifikt för jcmd 's Thread.print

När vi pratar om jcmd Thread.print kommando, är det ett bra tillfälle att illustrera hur du använder detta för att se trådstaplar av Java-processer. Nästa ögonblicksbild av skärmbilden visar början av de mycket längre resultat som ses när jcmd <pid> Thread.print exekveras (i detta fall för Java-processen med pid 6320).

Det finns flera VM.* kommandon som stöds av jcmd :VM.version , VM.uptime , VM.command_line , VM.flags , VM.system_properties , VM.native_memory och VM.classloader_stats . Nästa skärmbild illustrerar användningen av jcmd <pid> VM.version och jcmd <pid> VM.uptime för Java-processen med pid 6320.

Nästa skärmbild visar exekvering av jcmd <pid> VM.command_line mot process med pid 6320.

Från denna skärmbild som visar den övre delen av utdata från att köra jcmd 6320 VM.command_line , kan vi se från JVM-kommandoradsargumenten som gavs till den här processen att det är en NetBeans-relaterad process. Kör kommandot jcmd <pid> VM.flags mot Java-processen med pid 6320 visar HotSpot-alternativen som skickas till den processen.

Systemegenskaperna som används av en Java-process kan listas med jcmd <pid> VM.system_properties och detta illustreras i nästa skärmbild.

När man försöker köra jcmd <pid> VM.native_memory mot en Java-process som inte har haft Native Memory Tracking (NMT) aktiverat, skrivs felmeddelandet "Native Memory Tracking är inte aktiverat" ut som visas i nästa skärmbild.

För att använda kommandot jcmd <pid> VM.native_memory , bör JVM (java-processen) som ska mätas startas med antingen -XX:NativeMemoryTracking=summary eller -XX:NativeMemoryTracking=detail alternativ. När den virtuella datorn har startats med något av dessa alternativ, kommandona jcmd <pid> VM.native_memory baseline och sedan jcmd <pid> VM.native_memory detail.diff kan köras mot den JVM-processen.

Kommandot jcmd <pid> VM.classloader_stats ger insikt i klassladdaren. Detta visas i nästa skärmbild mot Java-processen med pid 1216:

jcmd <pid> VM.class_hierarchy är ett intressant kommando som skriver ut hierarkin för klasserna som laddas i den riktade Java VM-processen.

jcmd <pid> VM.dynlibs kan användas för att visa information om dynamiska bibliotek. Detta visas i nästa skärmbild när det körs mot Java-processen med pid 1216.

jcmd <pid> VM.info listar mycket information om den riktade Java VM-processen, inklusive en VM-sammanfattning och information om processen, sopsamlingshändelser, dynamiska bibliotek, argument som tillhandahålls till VM:n och några av värddatorns egenskaper. Bara en liten del av början av resultatet av detta visas i nästa skärmbild för jcmd 1216 VM.info :

Nästa skärmbild visar användningen av jcmd <pid> VM.stringtable och jcmd <pid> VM.symboltable :

Användning av jcmd <pid> Compiler.directives_print visas i nästa skärmbild.

Flera kommandon stöds av jcmd stödja hantering och övervakning av sophämtning. Två av dessa är jcmd <pid> GC.run [liknande System.gc()] och jcmd <pid> GC.run_finalization [liknande System.runFinalization()]. De två av dessa visas i nästa skärmbild.

Kommandot jcmd <pid> GC.class_histogram ger ett praktiskt sätt att visa ett objekthistogram som visas i nästa skärmbild.

jcmd kan användas för att generera en heap-dump mot en Java VM som körs med jcmd <pid> GC.heap_dump <filename> och detta visas i nästa skärmbild.

Kommandot jhat kan nu användas för att bearbeta heapdumpen som genereras av jcmd som visas i de nästa två skärmbilderna.

Det finns några jcmd kommandon som bara fungerar mot virtuella Java-datorer som startades med -XX:+UnlockDiagnosticVMOptions JVM flagga. Nästa skärmbild visar vad som händer när jag försöker köra jcmd <pid> GC.class_stats mot en Java VM som inte startades med flaggan -XX:+UnlockDiagnosticVMOptions .

När den riktade virtuella datorn startas med -XX:+UnlockDiagnosticVMOptions , jcmd <pid> GC.class_stats visar "statistik om Java-klassmetadata."

Det här inlägget har täckt flera av kommandona som tillhandahålls av jcmd , men har inte täckt funktionaliteten relaterad till Java Flight Recorder [JFR] (kommandon med namn som börjar med JFR.* ), för att kontrollera och aktivera kommersiella funktioner (jcmd <pid> VM.check_commercial_features och jcmd <pid> VM.unlock_commercial_features ).

I ett kommandoradsverktyg samlar jcmd funktionaliteten hos flera kommandorads-JDK-verktyg. Det här inlägget har demonstrerat flera av funktionerna som tillhandahålls av jcmd .

Java-tagg