VOOZH about

URL: https://www.javacodegeeks.com/2016/05/programmatic-jcmd-access.html

⇱ Programmatic jcmd Access - Java Code Geeks


Questions posed online demonstrate the occasional desire of developers to access via their Java applications the types of information normally gained from running JConsole, VisualVM, or JDK command-line tools externally against the application. Here are some examples of those types of questions:

I recently blogged on the usefulness of jcmd. This “Swiss-army knife” of command-line JDK tools provides much information about running Java processes and many of the types of information developers might want to acquire programatically are available via jcmd.

The Tools Enhancements in JDK 8 page states, “JDK 8 provides remote access to diagnostic commands which were previously accessible only locally via the jcmd tool. Remote access is provided using the Java Management Extensions (JMX), so diagnostic commands are exposed to a platform MBean registered to the platform MBean server. The MBean is the com.sun.management.DiagnosticCommandMBean interface.” In the post Looking at DiagnosticCommandMBean in JConsole and VisualVM, I looked at using JMX and DiagnosticCommandMBean via JConsole and VisualVM to access jcmd type information on a running JVM process.

In this post I look at how to use com.sun.management.DiagnosticCommandMBean to programmatically access information provided by jcmd.

The DiagnosticCommandMBean is accessed via JMX using the ObjectNamecom.sun.management:type=DiagnosticCommand“. Most of the operations require no arguments and return a String. With this in mind, a general approach to accessing these operations that have String[] signatures, a String return type, and don’t actually require a parameter is shown in the following code snippet.

Setting Up DiagnosticCommandMBean and General Method for Accessing Operations of Same Signature

/** Object Name of DiagnosticCommandMBean. */
 public final static String DIAGNOSTIC_COMMAND_MBEAN_NAME =
 "com.sun.management:type=DiagnosticCommand";

 /** My MBean Server. */
 private final MBeanServer server = ManagementFactory.getPlatformMBeanServer();

 /** Platform MBean Server. */
 private final ObjectName objectName;

 // . . .

 /**
 * Invoke operation on the DiagnosticCommandMBean that accepts
 * String array argument but does not require any String
 * argument and returns a String.
 *
 * @param operationName Name of operation on DiagnosticCommandMBean.
 * @param operationDescription Description of operation being invoked
 * on the DiagnosticCommandMBean.
 * @return String returned by DiagnosticCommandMBean operation.
 */
 private String invokeNoStringArgumentsCommand(
 final String operationName, final String operationDescription)
 {
 String result;
 try
 {
 result = (String) server.invoke(objectName, operationName, new Object[] {null}, new String[]{String[].class.getName()});
 }
 catch (InstanceNotFoundException | ReflectionException | MBeanException exception)
 {
 result = "ERROR: Unable to access '" + operationDescription + "' - " + exception;
 }
 return result;
 }

With the code above in place, the method invokeNoStringArgumentsCommand(String, String) can be used to access several of the operations that DiagnosticCommandMBean provides. The help sub-command is useful when used with jcmd because it lists the available sub-commands associated with a specified Java process. Likewise, the “help” operation provided by the DiagnosticCommandMBean is similarly helpful in providing a list of commands that the MBean supports. This is easy to access with the code shown next that uses the code just shown.

/**
 * Provide list of supported operations (help).
 *
 * @return Single string containing names of supported operations.
 */
public String getAvailableOperations()
{
 return invokeNoStringArgumentsCommand("help", "Help (List Commands)");
}

Running this from a simple Java application leads to output similar to that shown next:

The following commands are available:
JFR.stop
JFR.start
JFR.dump
JFR.check
VM.native_memory
VM.check_commercial_features
VM.unlock_commercial_features
GC.rotate_log
Thread.print
GC.class_stats
GC.class_histogram
GC.run_finalization
GC.run
VM.uptime
VM.flags
VM.system_properties
VM.command_line
VM.version
help

For more information about a specific command use 'help '.

In my blog post Determining the Active HotSpot Garbage Collector, I wrote that jcmd can be used to identify the VM flags of a running Java process and that, from those flags, one can glean which garbage collector is in use. Because the DiagnosticCommandMBean supports the VM.flags operation as shown above, this operation can be used to view the VM flags and, from those flags, determine which collector is in use. The next code listing shows two example methods with the first accessing the VM flags of the process and the second method providing a simplistic example of how to use the first method to identify the garbage collector in use.

Obtain Virtual Machine Flags and Identify Active Garbage Collector

/**
 * Provide a String representing the Virtual Machine flags.
 *
 * @return String containing the virtual machine flags.
 */
public String getVirtualMachineFlags()
{
 return invokeNoStringArgumentsCommand("vmFlags", "Determine VM flags");
}

/**
 * Provide String representing active/current garbage collector.
 *
 * @return String representation of current garbage collector
 * ("Parallel/Throughput", "Concurrent Mark Sweep (CMS)",
 * "Garbage First", or "UNDETERMINED").
 */
public String determineGarbageCollector()
{
 String garbageCollector;
 final String vmFlags = getVirtualMachineFlags();
 if (vmFlags.contains("+UseParallelGC") || vmFlags.contains("+UseParallelOldGC"))
 {
 garbageCollector = "Parallel/Throughput";
 }
 else if (vmFlags.contains("+UseConcMarkSweepGC"))
 {
 garbageCollector = "Concurrent Mark Sweep (CMS)";
 }
 else if (vmFlags.contains("+UseG1GC"))
 {
 garbageCollector = "Garbage First";
 }
 else
 {
 garbageCollector = "UNDETERMINED";
 }
 return garbageCollector;
}

The String with the VM flags and the output of the identified garbage collector are shown next:

-XX:CICompilerCount=3 -XX:InitialHeapSize=134217728 -XX:MaxHeapSize=2128609280 -XX:MaxNewSize=709361664 -XX:MinHeapDeltaBytes=524288 -XX:NewSize=44564480 -XX:OldSize=89653248 -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:-UseLargePagesIndividualAllocation -XX:+UseParallelGC
Parallel/Throughput

The examples already shown (accessing help and VM flags) are demonstrative of the same general approach that can be used to programmatically access other operations on DiagnosticCommandMBean with the same signature. A series of code listings and corresponding output are shown next to illustrate some of these.

Accessing Virtual Machine Uptime

/**
 * Provide virtual machine uptime as single String.
 *
 * @return Single string containing virtual machine uptime.
 */
public String getVirtualMachineUptime()
{
 return invokeNoStringArgumentsCommand("vmUptime", "Virtual Machine Uptime");
}
0.272 s

Accessing Thread Dump

/**
 * Provide thread dump as single String.
 *
 * @return Single string containing formatted thread dump.
 */
public String getThreadDump()
{
 return invokeNoStringArgumentsCommand("threadPrint", "Thread Dump");
}
2016-04-30 20:21:22
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.25-b02 mixed mode):

"Monitor Ctrl-Break" #10 daemon prio=5 os_prio=0 tid=0x00000000189ea800 nid=0x1590 runnable [0x000000001903e000]
 java.lang.Thread.State: RUNNABLE
 at java.net.DualStackPlainSocketImpl.accept0(Native Method)
 at java.net.DualStackPlainSocketImpl.socketAccept(DualStackPlainSocketImpl.java:131)
 at java.net.AbstractPlainSocketImpl.accept(AbstractPlainSocketImpl.java:404)
 at java.net.PlainSocketImpl.accept(PlainSocketImpl.java:199)
 - locked <0x0000000081208810> (a java.net.SocksSocketImpl)
 at java.net.ServerSocket.implAccept(ServerSocket.java:545)
 at java.net.ServerSocket.accept(ServerSocket.java:513)
 at com.intellij.rt.execution.application.AppMain$1.run(AppMain.java:90)
 at java.lang.Thread.run(Thread.java:745)

"Service Thread" #9 daemon prio=9 os_prio=0 tid=0x0000000018915800 nid=0x2468 runnable [0x0000000000000000]
 java.lang.Thread.State: RUNNABLE

"C1 CompilerThread2" #8 daemon prio=9 os_prio=2 tid=0x0000000017087000 nid=0x17a0 waiting on condition [0x0000000000000000]
 java.lang.Thread.State: RUNNABLE

"C2 CompilerThread1" #7 daemon prio=9 os_prio=2 tid=0x0000000017080000 nid=0x1560 waiting on condition [0x0000000000000000]
 java.lang.Thread.State: RUNNABLE

"C2 CompilerThread0" #6 daemon prio=9 os_prio=2 tid=0x000000001707d000 nid=0x2004 waiting on condition [0x0000000000000000]
 java.lang.Thread.State: RUNNABLE

"Attach Listener" #5 daemon prio=5 os_prio=2 tid=0x000000001707b000 nid=0x2160 runnable [0x0000000000000000]
 java.lang.Thread.State: RUNNABLE

"Signal Dispatcher" #4 daemon prio=9 os_prio=2 tid=0x000000001707a000 nid=0x458 runnable [0x0000000000000000]
 java.lang.Thread.State: RUNNABLE

"Finalizer" #3 daemon prio=8 os_prio=1 tid=0x00000000024f7000 nid=0x1964 in Object.wait() [0x00000000183ef000]
 java.lang.Thread.State: WAITING (on object monitor)
 at java.lang.Object.wait(Native Method)
 - waiting on <0x0000000081201570> (a java.lang.ref.ReferenceQueue$Lock)
 at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:142)
 - locked <0x0000000081201570> (a java.lang.ref.ReferenceQueue$Lock)
 at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:158)
 at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:209)

"Reference Handler" #2 daemon prio=10 os_prio=2 tid=0x00000000024ee000 nid=0x270c in Object.wait() [0x00000000182ef000]
 java.lang.Thread.State: WAITING (on object monitor)
 at java.lang.Object.wait(Native Method)
 - waiting on <0x0000000081208c28> (a java.lang.ref.Reference$Lock)
 at java.lang.Object.wait(Object.java:502)
 at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:157)
 - locked <0x0000000081208c28> (a java.lang.ref.Reference$Lock)

"main" #1 prio=5 os_prio=0 tid=0x0000000000c4e000 nid=0x24f8 waiting on condition [0x0000000000dee000]
 java.lang.Thread.State: RUNNABLE
 at sun.management.DiagnosticCommandImpl.executeDiagnosticCommand(Native Method)
 at sun.management.DiagnosticCommandImpl.access$000(DiagnosticCommandImpl.java:40)
 at sun.management.DiagnosticCommandImpl$Wrapper.execute(DiagnosticCommandImpl.java:128)
 at sun.management.DiagnosticCommandImpl.invoke(DiagnosticCommandImpl.java:230)
 at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:819)
 at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:801)
 at dustin.examples.diagnostics.VirtualMachineDiagnostics.invokeNoStringArgumentsCommand(VirtualMachineDiagnostics.java:167)
 at dustin.examples.diagnostics.VirtualMachineDiagnostics.getThreadDump(VirtualMachineDiagnostics.java:88)
 at dustin.examples.diagnostics.VirtualMachineDiagnostics.main(VirtualMachineDiagnostics.java:187)
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
 at java.lang.reflect.Method.invoke(Method.java:483)
 at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)

"VM Thread" os_prio=2 tid=0x0000000017046000 nid=0x22b0 runnable 

"GC task thread#0 (ParallelGC)" os_prio=0 tid=0x0000000002417800 nid=0x1580 runnable 

"GC task thread#1 (ParallelGC)" os_prio=0 tid=0x0000000002419000 nid=0x16d8 runnable 

"GC task thread#2 (ParallelGC)" os_prio=0 tid=0x000000000241a800 nid=0x177c runnable 

"GC task thread#3 (ParallelGC)" os_prio=0 tid=0x000000000241c800 nid=0x1974 runnable 

"VM Periodic Task Thread" os_prio=2 tid=0x0000000018918000 nid=0x10dc waiting on condition 

JNI global references: 15

Getting Class Histogram

/**
 * Provide class histogram as single String.
 *
 * @return Single string containing formatted class histogram.
 */
public String getHistogram()
{
 return invokeNoStringArgumentsCommand("gcClassHistogram", "GC Class Histogram");
}
num #instances #bytes class name
----------------------------------------------
 1: 3485 243064 [C
 2: 467 124976 [B
 3: 992 104200 java.lang.Class
 4: 3452 82848 java.lang.String
 5: 1006 46744 [Ljava.lang.Object;
 6: 525 46200 java.lang.reflect.Method
 7: 309 22248 java.lang.reflect.Field
 8: 519 16608 java.util.HashMap$Node
 9: 326 11760 [Ljava.lang.String;
 10: 211 8968 [I
 11: 434 8312 [Ljava.lang.Class;
 12: 77 7416 [Ljava.util.HashMap$Node;
 13: 179 7160 java.lang.ref.SoftReference
 14: 101 5656 java.lang.Class$ReflectionData
 15: 73 4672 java.net.URL
 16: 97 4656 java.util.HashMap
 17: 89 4560 [Ljava.lang.reflect.Method;
 18: 189 4536 javax.management.ImmutableDescriptor
 19: 279 4464 java.lang.Integer
 20: 139 4448 java.util.Hashtable$Entry
 21: 105 4200 java.util.WeakHashMap$Entry
 22: 129 4128 java.util.concurrent.ConcurrentHashMap$Node
 23: 128 4096 com.sun.jmx.mbeanserver.ConvertingMethod
 24: 90 3600 java.util.TreeMap$Entry
 25: 34 3360 [Ljava.util.WeakHashMap$Entry;
 26: 8 3008 java.lang.Thread
 27: 45 2880 javax.management.openmbean.OpenMBeanAttributeInfoSupport
 28: 87 2784 java.lang.ref.WeakReference
 29: 160 2560 java.lang.Object
 30: 49 2544 [Ljavax.management.MBeanAttributeInfo;
 31: 135 2536 [Lcom.sun.jmx.mbeanserver.MXBeanMapping;
 32: 30 2400 java.lang.reflect.Constructor
 33: 48 2304 javax.management.MBeanInfo
 34: 49 1960 java.io.ObjectStreamField
 35: 60 1920 javax.management.MBeanAttributeInfo
 36: 46 1840 java.util.LinkedHashMap$Entry
 37: 38 1824 sun.util.locale.LocaleObjectCache$CacheEntry
 38: 44 1760 java.lang.ref.Finalizer
 39: 30 1752 [Ljava.lang.reflect.Field;
 40: 36 1728 sun.misc.URLClassPath$JarLoader
 41: 1 1712 [[B
 42: 40 1600 sun.management.DiagnosticCommandArgumentInfo
 43: 31 1488 java.util.WeakHashMap
 44: 60 1440 java.util.ArrayList
 45: 11 1392 [Ljava.util.Hashtable$Entry;
 46: 42 1344 java.lang.ref.ReferenceQueue
 47: 2 1320 [J
 48: 10 1312 [Ljava.util.concurrent.ConcurrentHashMap$Node;
 49: 26 1248 java.util.logging.LogManager$LoggerWeakRef
 50: 47 1120 [Ljavax.management.ObjectName$Property;
 51: 1 1040 [Ljava.lang.Integer;
 52: 39 1008 [Ljavax.management.MBeanOperationInfo;
 53: 24 960 javax.management.ObjectName
 54: 38 912 java.io.ExpiringCache$Entry
 55: 19 912 sun.management.DiagnosticCommandInfo
 56: 18 864 java.util.TreeMap
 57: 12 864 java.util.logging.Logger
 58: 35 840 javax.management.ObjectName$Property
 59: 15 840 javax.management.openmbean.ArrayType
 60: 20 800 com.sun.jmx.mbeanserver.MXBeanSupport
 61: 20 800 javax.management.MBeanOperationInfo
 62: 14 784 sun.nio.cs.UTF_8$Encoder
 63: 32 768 com.sun.jmx.mbeanserver.DefaultMXBeanMappingFactory$IdentityMapping
 64: 12 768 java.util.jar.JarFile
 65: 19 760 sun.util.locale.BaseLocale$Key
 66: 15 720 java.lang.management.PlatformComponent
 67: 44 704 java.lang.ref.ReferenceQueue$Lock
 68: 11 704 java.util.concurrent.ConcurrentHashMap
 69: 21 672 com.sun.jmx.mbeanserver.WeakIdentityHashMap$IdentityWeakReference
 70: 7 672 java.util.jar.JarFile$JarFileEntry
 71: 12 672 java.util.zip.ZipFile$ZipFileInputStream
 72: 19 608 java.util.Locale
 73: 19 608 sun.management.DiagnosticCommandImpl$Wrapper
 74: 19 608 sun.util.locale.BaseLocale
 75: 18 576 javax.management.MBeanParameterInfo
 76: 10 560 java.util.LinkedHashMap
 77: 14 560 javax.management.openmbean.SimpleType
 78: 23 552 com.sun.jmx.mbeanserver.PerInterface$MethodAndSig
 79: 26 536 [Ljava.lang.reflect.Constructor;
 80: 22 528 com.sun.jmx.mbeanserver.NamedObject
 81: 22 528 sun.reflect.generics.tree.SimpleClassTypeSignature
 82: 13 520 java.security.AccessControlContext
 83: 16 512 java.util.logging.LogManager$LogNode
 84: 17 504 [Ljava.io.ObjectStreamField;
 85: 9 504 javax.management.openmbean.CompositeType
 86: 19 488 [Lsun.management.DiagnosticCommandArgumentInfo;
 87: 12 480 com.sun.jmx.mbeanserver.PerInterface
 88: 20 480 java.lang.Class$AnnotationData
 89: 20 480 java.util.Arrays$ArrayList
 90: 20 480 java.util.jar.Attributes$Name
 91: 19 456 [Ljavax.management.MBeanParameterInfo;
 92: 19 456 java.util.Locale$LocaleKey
 93: 14 448 java.util.concurrent.locks.ReentrantLock$NonfairSync
 94: 8 448 javax.management.openmbean.OpenMBeanParameterInfoSupport
 95: 20 440 [Ljavax.management.MBeanNotificationInfo;
 96: 13 416 java.io.File
 97: 22 408 [Lsun.reflect.generics.tree.TypeArgument;
 98: 10 400 java.io.FileDescriptor
 99: 10 400 sun.reflect.UnsafeQualifiedStaticObjectFieldAccessorImpl
 100: 1 384 java.lang.ref.Finalizer$FinalizerThread
 101: 6 384 java.nio.DirectByteBuffer
 102: 8 384 java.util.Hashtable
 103: 1 384 java.util.logging.LogManager$Cleaner
 104: 12 384 java.util.zip.ZipCoder
 105: 1 376 java.lang.ref.Reference$ReferenceHandler
 106: 15 360 javax.management.StandardMBean
 107: 22 352 sun.reflect.generics.tree.ClassTypeSignature
 108: 4 336 [D
 109: 7 336 com.sun.jmx.mbeanserver.DefaultMXBeanMappingFactory$CompositeMapping
 110: 6 336 java.nio.DirectLongBufferU
 111: 14 336 java.util.concurrent.CopyOnWriteArrayList
 112: 6 336 sun.management.MemoryPoolImpl
 113: 14 336 sun.reflect.NativeConstructorAccessorImpl
 114: 16 328 [Ljava.lang.management.PlatformComponent;
 115: 4 320 [S
 116: 13 312 java.lang.management.ManagementPermission
 117: 9 288 java.lang.OutOfMemoryError
 118: 12 288 java.util.ArrayDeque
 119: 12 288 java.util.Collections$SingletonList
 120: 9 288 java.util.logging.Level
 121: 12 288 sun.misc.MetaIndex
 122: 5 280 sun.util.calendar.ZoneInfo
 123: 8 256 sun.misc.ProxyGenerator$PrimitiveTypeInfo
 124: 2 240 java.net.SocksSocketImpl
 125: 6 240 sun.management.MemoryPoolImpl$CollectionSensor
 126: 6 240 sun.management.MemoryPoolImpl$PoolSensor
 127: 6 240 sun.reflect.generics.repository.MethodRepository
 128: 14 224 java.util.concurrent.locks.ReentrantLock
 129: 14 224 sun.reflect.DelegatingConstructorAccessorImpl
 130: 13 216 [Ljavax.management.MBeanConstructorInfo;
 131: 9 216 java.util.logging.Level$KnownLevel
 132: 9 216 sun.util.logging.PlatformLogger$Level
 133: 10 208 [Ljava.lang.reflect.Type;
 134: 5 200 java.lang.ClassLoader$NativeLibrary
 135: 6 192 java.util.Vector
 136: 8 192 sun.reflect.generics.factory.CoreReflectionFactory
 137: 6 192 sun.reflect.generics.tree.MethodTypeSignature
 138: 2 176 java.net.DualStackPlainSocketImpl
 139: 9 168 [Lsun.reflect.generics.tree.FieldTypeSignature;
 140: 3 168 javax.management.openmbean.OpenMBeanOperationInfoSupport
 141: 9 160 [Lsun.reflect.generics.tree.FormalTypeParameter;
 142: 5 160 java.io.FileInputStream
 143: 4 160 java.security.ProtectionDomain
 144: 5 160 javax.management.MBeanNotificationInfo
 145: 5 160 javax.management.StandardEmitterMBean
 146: 6 144 java.util.LinkedList$Node
 147: 3 144 java.util.Properties
 148: 6 144 sun.misc.PerfCounter
 149: 6 144 sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl
 150: 6 144 sun.reflect.generics.scope.MethodScope
 151: 4 128 com.sun.jmx.mbeanserver.DefaultMXBeanMappingFactory$ArrayMapping
 152: 2 128 java.io.ExpiringCache$1
 153: 4 128 java.security.CodeSource
 154: 8 128 java.util.HashSet
 155: 4 128 java.util.LinkedList
 156: 1 120 [[Ljava.lang.String;
 157: 5 120 sun.misc.FloatingDecimal$PreparedASCIIToBinaryBuffer
 158: 2 112 java.lang.Package
 159: 2 112 java.util.zip.ZipFile$ZipFileInflaterInputStream
 160: 1 96 [Ljava.lang.invoke.MethodType;
 161: 6 96 [Lsun.reflect.generics.tree.TypeSignature;
 162: 3 96 com.sun.jmx.mbeanserver.DefaultMXBeanMappingFactory$EnumMapping
 163: 4 96 java.lang.RuntimePermission
 164: 2 96 java.lang.ThreadGroup
 165: 6 96 java.lang.ThreadLocal
 166: 2 96 java.nio.HeapByteBuffer
 167: 4 96 java.util.Collections$UnmodifiableRandomAccessList
 168: 3 96 java.util.Stack
 169: 2 96 java.util.zip.Inflater
 170: 2 96 javax.management.openmbean.TabularType
 171: 2 96 sun.management.GarbageCollectorImpl
 172: 2 96 sun.nio.cs.StreamEncoder
 173: 4 96 sun.reflect.annotation.AnnotationInvocationHandler
 174: 3 96 sun.reflect.generics.reflectiveObjects.TypeVariableImpl
 175: 3 96 sun.reflect.generics.repository.ClassRepository
 176: 1 88 sun.misc.Launcher$AppClassLoader
 177: 1 88 sun.misc.Launcher$ExtClassLoader
 178: 1 80 [Ljava.lang.ThreadLocal$ThreadLocalMap$Entry;
 179: 1 80 [Ljava.lang.invoke.LambdaForm;
 180: 2 80 com.sun.jmx.mbeanserver.DefaultMXBeanMappingFactory$TabularMapping
 181: 2 80 java.io.BufferedWriter
 182: 2 80 java.io.ExpiringCache
 183: 2 80 java.lang.invoke.MethodType
 184: 2 80 java.util.IdentityHashMap
 185: 2 80 sun.management.MemoryManagerImpl
 186: 2 80 sun.misc.FloatingDecimal$BinaryToASCIIBuffer
 187: 2 80 sun.misc.URLClassPath
 188: 1 72 [Ljavax.management.openmbean.SimpleType;
 189: 3 72 java.lang.annotation.RetentionPolicy
 190: 1 72 java.lang.invoke.MethodTypeForm
 191: 3 72 java.net.InetAddress$InetAddressHolder
 192: 3 72 java.util.Collections$SynchronizedSet
 193: 1 72 java.util.logging.LogManager$RootLogger
 194: 3 72 sun.misc.FloatingDecimal$ExceptionalBinaryToASCIIBuffer
 195: 3 72 sun.reflect.NativeMethodAccessorImpl
 196: 3 72 sun.reflect.generics.tree.ClassSignature
 197: 3 72 sun.reflect.generics.tree.FormalTypeParameter
 198: 1 64 [F
 199: 2 64 [Ljava.lang.Thread;
 200: 2 64 [Ljava.lang.annotation.RetentionPolicy;
 201: 4 64 [Ljava.security.Principal;
 202: 2 64 com.sun.jmx.mbeanserver.DefaultMXBeanMappingFactory$CollectionMapping
 203: 4 64 com.sun.proxy.$Proxy1
 204: 2 64 java.io.FileOutputStream
 205: 2 64 java.io.FilePermission
 206: 2 64 java.io.PrintStream
 207: 2 64 java.lang.ThreadLocal$ThreadLocalMap$Entry
 208: 2 64 java.lang.VirtualMachineError
 209: 2 64 java.lang.invoke.MethodType$ConcurrentWeakInternSet$WeakEntry
 210: 2 64 java.lang.ref.ReferenceQueue$Null
 211: 2 64 java.lang.reflect.Proxy$Key1
 212: 2 64 java.lang.reflect.WeakCache$CacheValue
 213: 2 64 java.security.BasicPermissionCollection
 214: 2 64 java.security.Permissions
 215: 4 64 java.security.ProtectionDomain$Key
 216: 4 64 java.util.LinkedHashMap$LinkedValues
 217: 2 64 java.util.PropertyPermission
 218: 2 64 sun.reflect.annotation.AnnotationType
 219: 1 56 [Ljava.lang.Runnable;
 220: 3 56 [Lsun.reflect.generics.tree.ClassTypeSignature;
 221: 1 56 [Lsun.util.logging.PlatformLogger$Level;
 222: 1 56 java.lang.invoke.MemberName
 223: 1 56 java.util.logging.LogManager
 224: 3 48 [Ljava.lang.annotation.Annotation;
 225: 2 48 [Ljava.lang.reflect.TypeVariable;
 226: 1 48 [[Ljava.lang.Object;
 227: 2 48 com.sun.jmx.mbeanserver.ClassLoaderRepositorySupport$LoaderEntry
 228: 1 48 com.sun.jmx.mbeanserver.DefaultMXBeanMappingFactory$Mappings
 229: 1 48 com.sun.jmx.mbeanserver.MBeanIntrospector$MBeanInfoMap
 230: 1 48 com.sun.jmx.mbeanserver.MBeanIntrospector$PerInterfaceMap
 231: 2 48 com.sun.jmx.mbeanserver.WeakIdentityHashMap
 232: 2 48 java.io.BufferedOutputStream
 233: 2 48 java.io.File$PathStatus
 234: 2 48 java.io.FilePermissionCollection
 235: 2 48 java.io.OutputStreamWriter
 236: 2 48 java.lang.StringBuilder
 237: 2 48 java.net.InetAddress
 238: 2 48 java.net.InetAddress$Cache
 239: 2 48 java.net.InetAddress$Cache$Type
 240: 2 48 java.nio.charset.CoderResult
 241: 3 48 java.nio.charset.CodingErrorAction
 242: 1 48 java.util.concurrent.locks.ReentrantReadWriteLock$FairSync
 243: 2 48 java.util.logging.Logger$LoggerBundle
 244: 2 48 java.util.zip.ZStreamRef
 245: 2 48 sun.management.ManagementFactoryHelper$1
 246: 2 48 sun.misc.NativeSignalHandler
 247: 2 48 sun.misc.Signal
 248: 1 48 sun.nio.cs.SingleByte$Decoder
 249: 3 48 sun.reflect.DelegatingMethodAccessorImpl
 250: 2 48 sun.reflect.generics.scope.ClassScope
 251: 2 40 [Lcom.sun.jmx.mbeanserver.ClassLoaderRepositorySupport$LoaderEntry;
 252: 1 40 [Ljava.lang.management.MemoryPoolMXBean;
 253: 1 40 com.sun.jmx.interceptor.DefaultMBeanServerInterceptor
 254: 1 40 com.sun.jmx.mbeanserver.JmxMBeanServer
 255: 1 40 com.sun.jmx.mbeanserver.MBeanServerDelegateImpl
 256: 1 40 java.io.BufferedInputStream
 257: 1 40 sun.management.DiagnosticCommandImpl
 258: 1 40 sun.nio.cs.StandardCharsets$Aliases
 259: 1 40 sun.nio.cs.StandardCharsets$Cache
 260: 1 40 sun.nio.cs.StandardCharsets$Classes
 261: 1 40 sun.nio.cs.UTF_8$Decoder
 262: 1 32 [Ljava.lang.OutOfMemoryError;
 263: 2 32 [Ljava.lang.StackTraceElement;
 264: 1 32 [Ljava.lang.ThreadGroup;
 265: 1 32 [Ljava.lang.management.MemoryManagerMXBean;
 266: 1 32 com.sun.jmx.mbeanserver.Repository
 267: 1 32 java.io.WinNTFileSystem
 268: 1 32 java.lang.ArithmeticException
 269: 2 32 java.lang.Boolean
 270: 1 32 java.lang.NullPointerException
 271: 2 32 java.lang.Shutdown$Lock
 272: 1 32 java.lang.StringCoding$StringDecoder
 273: 1 32 java.lang.reflect.WeakCache
 274: 1 32 java.net.Socket
 275: 2 32 java.nio.ByteOrder
 276: 1 32 java.util.Collections$UnmodifiableMap
 277: 2 32 java.util.HashMap$EntrySet
 278: 1 32 java.util.concurrent.atomic.AtomicReferenceFieldUpdater$AtomicReferenceFieldUpdaterImpl
 279: 1 32 java.util.logging.LogManager$SystemLoggerContext
 280: 1 32 javax.management.MBeanConstructorInfo
 281: 1 32 sun.management.MemoryImpl
 282: 2 32 sun.net.www.protocol.jar.Handler
 283: 1 32 sun.nio.cs.StandardCharsets
 284: 1 24 [Ljava.io.File$PathStatus;
 285: 1 24 [Ljava.lang.invoke.MethodHandle;
 286: 1 24 [Ljava.net.InetAddress$Cache$Type;
 287: 1 24 [Ljava.net.InetSocketAddress;
 288: 1 24 [Ljava.security.ProtectionDomain;
 289: 1 24 [Lsun.launcher.LauncherHelper;
 290: 1 24 com.sun.jmx.mbeanserver.ClassLoaderRepositorySupport
 291: 1 24 com.sun.jmx.mbeanserver.MXBeanLookup
 292: 1 24 com.sun.jmx.remote.util.ClassLogger
 293: 1 24 dustin.examples.diagnostics.VirtualMachineDiagnostics
 294: 1 24 java.lang.ThreadLocal$ThreadLocalMap
 295: 1 24 java.lang.invoke.LambdaForm$NamedFunction
 296: 1 24 java.lang.invoke.MethodType$ConcurrentWeakInternSet
 297: 1 24 java.lang.reflect.ReflectPermission
 298: 1 24 java.net.Inet4Address
 299: 1 24 java.net.Inet6AddressImpl
 300: 1 24 java.net.ServerSocket
 301: 1 24 java.util.BitSet
 302: 1 24 java.util.Collections$EmptyMap
 303: 1 24 java.util.Collections$SetFromMap
 304: 1 24 java.util.Locale$Cache
 305: 1 24 java.util.concurrent.atomic.AtomicLong
 306: 1 24 java.util.concurrent.locks.ReentrantReadWriteLock
 307: 1 24 java.util.jar.Manifest
 308: 1 24 java.util.logging.LogManager$LoggerContext
 309: 1 24 java.util.logging.LoggingPermission
 310: 1 24 javax.management.NotificationBroadcasterSupport
 311: 1 24 sun.launcher.LauncherHelper
 312: 1 24 sun.management.CompilationImpl
 313: 1 24 sun.management.OperatingSystemImpl
 314: 1 24 sun.management.RuntimeImpl
 315: 1 24 sun.management.ThreadImpl
 316: 1 24 sun.management.VMManagementImpl
 317: 1 24 sun.misc.JarIndex
 318: 1 24 sun.misc.URLClassPath$FileLoader
 319: 1 24 sun.nio.cs.ISO_8859_1
 320: 1 24 sun.nio.cs.MS1252
 321: 1 24 sun.nio.cs.ThreadLocalCoders$1
 322: 1 24 sun.nio.cs.ThreadLocalCoders$2
 323: 1 24 sun.nio.cs.US_ASCII
 324: 1 24 sun.nio.cs.UTF_16
 325: 1 24 sun.nio.cs.UTF_16BE
 326: 1 24 sun.nio.cs.UTF_16LE
 327: 1 24 sun.nio.cs.UTF_8
 328: 1 24 sun.util.locale.BaseLocale$Cache
 329: 1 16 [Ljava.lang.Throwable;
 330: 1 16 [Ljava.nio.file.attribute.FileAttribute;
 331: 1 16 [Ljava.security.cert.Certificate;
 332: 1 16 [Ljava.util.logging.Handler;
 333: 1 16 com.intellij.rt.execution.application.AppMain$1
 334: 1 16 com.sun.jmx.interceptor.DefaultMBeanServerInterceptor$ResourceContext$1
 335: 1 16 com.sun.jmx.mbeanserver.DefaultMXBeanMappingFactory
 336: 1 16 com.sun.jmx.mbeanserver.DescriptorCache
 337: 1 16 com.sun.jmx.mbeanserver.MBeanAnalyzer$MethodOrder
 338: 1 16 com.sun.jmx.mbeanserver.MBeanInstantiator
 339: 1 16 com.sun.jmx.mbeanserver.MXBeanIntrospector
 340: 1 16 com.sun.jmx.mbeanserver.SecureClassLoaderRepository
 341: 1 16 java.io.FileDescriptor$1
 342: 1 16 java.lang.ApplicationShutdownHooks$1
 343: 1 16 java.lang.CharacterDataLatin1
 344: 1 16 java.lang.Runtime
 345: 1 16 java.lang.String$CaseInsensitiveComparator
 346: 1 16 java.lang.System$2
 347: 1 16 java.lang.Terminator$1
 348: 1 16 java.lang.invoke.MemberName$Factory
 349: 1 16 java.lang.management.PlatformComponent$1
 350: 1 16 java.lang.management.PlatformComponent$10
 351: 1 16 java.lang.management.PlatformComponent$11
 352: 1 16 java.lang.management.PlatformComponent$12
 353: 1 16 java.lang.management.PlatformComponent$13
 354: 1 16 java.lang.management.PlatformComponent$14
 355: 1 16 java.lang.management.PlatformComponent$15
 356: 1 16 java.lang.management.PlatformComponent$2
 357: 1 16 java.lang.management.PlatformComponent$3
 358: 1 16 java.lang.management.PlatformComponent$4
 359: 1 16 java.lang.management.PlatformComponent$5
 360: 1 16 java.lang.management.PlatformComponent$6
 361: 1 16 java.lang.management.PlatformComponent$7
 362: 1 16 java.lang.management.PlatformComponent$8
 363: 1 16 java.lang.management.PlatformComponent$9
 364: 1 16 java.lang.ref.Reference$Lock
 365: 1 16 java.lang.reflect.Proxy$KeyFactory
 366: 1 16 java.lang.reflect.Proxy$ProxyClassFactory
 367: 1 16 java.lang.reflect.ReflectAccess
 368: 1 16 java.net.InetAddress$2
 369: 1 16 java.net.URLClassLoader$7
 370: 1 16 java.nio.Bits$1
 371: 1 16 java.nio.Bits$1$1
 372: 1 16 java.nio.charset.CoderResult$1
 373: 1 16 java.nio.charset.CoderResult$2
 374: 1 16 java.security.ProtectionDomain$1
 375: 1 16 java.security.ProtectionDomain$3
 376: 1 16 java.util.Collections$EmptyIterator
 377: 1 16 java.util.Collections$EmptyList
 378: 1 16 java.util.Collections$EmptySet
 379: 1 16 java.util.Collections$SingletonSet
 380: 1 16 java.util.HashMap$Values
 381: 1 16 java.util.Hashtable$EntrySet
 382: 1 16 java.util.WeakHashMap$KeySet
 383: 1 16 java.util.concurrent.atomic.AtomicInteger
 384: 1 16 java.util.concurrent.locks.ReentrantReadWriteLock$ReadLock
 385: 1 16 java.util.concurrent.locks.ReentrantReadWriteLock$Sync$ThreadLocalHoldCounter
 386: 1 16 java.util.concurrent.locks.ReentrantReadWriteLock$WriteLock
 387: 1 16 java.util.jar.Attributes
 388: 1 16 java.util.jar.JavaUtilJarAccessImpl
 389: 1 16 java.util.logging.LoggingProxyImpl
 390: 1 16 java.util.zip.ZipFile$1
 391: 1 16 javax.management.JMX
 392: 1 16 javax.management.MBeanServerBuilder
 393: 1 16 javax.management.NotificationBroadcasterSupport$1
 394: 1 16 sun.management.ClassLoadingImpl
 395: 1 16 sun.management.HotSpotDiagnostic
 396: 1 16 sun.management.ManagementFactoryHelper$PlatformLoggingImpl
 397: 1 16 sun.misc.ASCIICaseInsensitiveComparator
 398: 1 16 sun.misc.FloatingDecimal$1
 399: 1 16 sun.misc.Launcher
 400: 1 16 sun.misc.Launcher$Factory
 401: 1 16 sun.misc.Perf
 402: 1 16 sun.misc.Unsafe
 403: 1 16 sun.net.www.protocol.file.Handler
 404: 1 16 sun.nio.ch.FileChannelImpl$1
 405: 1 16 sun.reflect.ReflectionFactory
 406: 1 16 sun.reflect.generics.tree.TypeVariableSignature
 407: 1 16 sun.util.calendar.Gregorian
Total 16267 885480

Some of the sub-commands available with jcmd are only available when diagnostic operations are unlocked with -XX:+UnlockDiagnosticVMOptions (specified when running the Java process). This is true of the DiagnosticCommandMBean counterparts as demonstrated in the next code listing and output listing.

Accessing Class Statistics

/**
 * Provide class statistics as single String.
 *
 * This is only supported when {@code -XX:+UnlockDiagnosticVMOptions} is enabled.
 *
 * @return Single string containing formatted class statistics.
 */
public String getClassStatistics()
{
 return invokeNoStringArgumentsCommand("gcClassStats", "GC Class Statistics");
}
GC.class_stats command requires -XX:+UnlockDiagnosticVMOptions

One jcmd subcommand I have not seen exposed as an operation on DiagnosticCommandMBean is that for generating a heap dump (jcmd‘s GC.heap_dump). There is no equivalent operation exposed by DiagnosticCommandMBean as far as I can tell from looking at the exposed operations in VisualVM and JConsole and from looking at the available commands listed by the “help” operation as demonstrated above. Although DiagnosticCommandMBean does not appear to provide an operation for invoking a heap dump, another MBean (com.sun.management.HotSpotDiagnostic with ObjectName of “com.sun.management:type=HotSpotDiagnostic”) does with operation “dumpHeap” and this is demonstrated in A. Sundararajan‘s’s blog post “Programmatically dumping heap from Java applications.”

Conclusion

The DiagnosticCommandMBean provides most of jcmd‘s functionality and it therefore makes jcmd functionality available to Java applications to run that functionality against themselves.

The code listings shown in this post are available in the class VirtualMachineDiagnostics, which is available on GitHub. I may add or modify this class in the future, but the original version has the same code as shown in this post.

Reference: Programmatic jcmd Access from our JCG partner Dustin Marx at the Inspired by Actual Events blog.
Do you want to know how to develop your skillset to become a Java Rockstar?
Subscribe to our newsletter to start Rocking right now!
To get you started we give you our best selling eBooks for FREE!
1. JPA Mini Book
2. JVM Troubleshooting Guide
3. JUnit Tutorial for Unit Testing
4. Java Annotations Tutorial
5. Java Interview Questions
6. Spring Interview Questions
7. Android UI Design
and many more ....
I agree to the Terms and Privacy Policy

Thank you!

We will contact you soon.

Tags
jcmd
👁 Photo of Dustin Marx
Dustin Marx
May 4th, 2016Last Updated: May 2nd, 2016
0 682 13 minutes read
Subscribe

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Oldest
Newest Most Voted
Back to top button
Close
wpDiscuz