Вопросы, задаваемые в Интернете, демонстрируют случайное желание разработчиков получить доступ через свои приложения Java к типам информации, обычно получаемой от запуска инструментов командной строки JConsole , VisualVM или JDK извне по отношению к приложению. Вот несколько примеров таких вопросов:
- Как получить гистограмму jmap программно?
- Программный дамп кучи из приложений Java
- найти, какой тип сборщика мусора работает
Недавно я написал в блоге о полезности jcmd . Этот « швейцарский армейский нож » инструментов JDK командной строки предоставляет много информации о запущенных процессах Java, и многие из типов информации, которые разработчики могут захотеть получить программно, доступны через jcmd
.
На странице « Усовершенствования инструментов в JDK 8» говорится: «JDK 8 обеспечивает удаленный доступ к диагностическим командам, которые ранее были доступны только локально через инструмент jcmd
. Удаленный доступ предоставляется с помощью Java Management Extensions (JMX), поэтому диагностические команды доступны для платформы MBean, зарегистрированной на сервере MBean платформы. MBean — это интерфейс com.sun.management.DiagnosticCommandMBean
». В статье « Просмотр DiagnosticCommandMBean в JConsole и VisualVM» я рассмотрел использование JMX и DiagnosticCommandMBean через JConsole и VisualVM для доступа jcmd
информации о типе jcmd
в работающем процессе JVM.
В этой статье я расскажу, как использовать com.sun.management.DiagnosticCommandMBean для программного доступа к информации, предоставленной jcmd .
Доступ к DiagnosticCommandMBean осуществляется через JMX с использованием ObjectName « com.sun.management:type=DiagnosticCommand
». Большинство операций не требуют аргументов и возвращают String
. Имея это в виду, в следующем фрагменте кода показан общий подход к доступу к этим операциям, которые имеют сигнатуры String[]
, возвращаемый тип String
и на самом деле не нуждаются в параметре.
Настройка DiagnosticCommandMBean и общего метода для доступа к операциям той же подписи
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
/** 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; } |
С помощью приведенного выше кода метод invokeNoStringArgumentsCommand(String, String)
можно использовать для доступа к нескольким операциям, которые обеспечивает DiagnosticCommandMBean
. jcmd
полезна при использовании с jcmd
поскольку в ней перечислены доступные jcmd
связанные с указанным процессом Java. Аналогично, операция «помощь», предоставляемая DiagnosticCommandMBean
, также полезна при предоставлении списка команд, которые поддерживает MBean. Это легко получить с помощью приведенного ниже кода, который использует только что показанный код.
1
2
3
4
5
6
7
8
9
|
/** * Provide list of supported operations (help). * * @return Single string containing names of supported operations. */ public String getAvailableOperations() { return invokeNoStringArgumentsCommand( "help" , "Help (List Commands)" ); } |
Запуск этого из простого Java-приложения приводит к выводу, подобному показанному ниже:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
|
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 ' . |
В своем блоге « Определение активного сборщика мусора HotSpot» я написал, что jcmd
можно использовать для определения флагов виртуальных jcmd
работающего процесса Java и что из этих флагов можно определить, какой сборщик мусора используется. Поскольку DiagnosticCommandMBean
поддерживает операцию VM.flags
как показано выше, эту операцию можно использовать для просмотра флагов VM и, VM.flags
из этих флагов, определить, какой сборщик используется. В следующем листинге кода показаны два примера методов, первый из которых обращается к флагам VM процесса, а второй — упрощенный пример использования первого метода для идентификации используемого сборщика мусора.
Получите флаги виртуальной машины и определите активный сборщик мусора
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
/** * 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; } |
Строка с флагами VM и выходные данные идентифицированного сборщика мусора показаны ниже:
1
|
-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 |
1
|
Parallel/Throughput |
Уже показанные примеры (доступ к справке и флаги VM) демонстрируют тот же общий подход, который можно использовать для программного доступа к другим операциям в DiagnosticCommandMBean
с той же сигнатурой. Ряд списков кода и соответствующие выходные данные показаны рядом, чтобы проиллюстрировать некоторые из них.
Доступ к виртуальной машине
1
2
3
4
5
6
7
8
9
|
/** * Provide virtual machine uptime as single String. * * @return Single string containing virtual machine uptime. */ public String getVirtualMachineUptime() { return invokeNoStringArgumentsCommand( "vmUptime" , "Virtual Machine Uptime" ); } |
1
|
0.272 s |
Доступ к дампу потока
1
2
3
4
5
6
7
8
9
|
/** * Provide thread dump as single String. * * @return Single string containing formatted thread dump. */ public String getThreadDump() { return invokeNoStringArgumentsCommand( "threadPrint" , "Thread Dump" ); } |
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
|
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 |
Получение гистограммы классов
1
2
3
4
5
6
7
8
9
|
/** * Provide class histogram as single String. * * @return Single string containing formatted class histogram. */ public String getHistogram() { return invokeNoStringArgumentsCommand( "gcClassHistogram" , "GC Class Histogram" ); } |
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
|
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 |
Некоторые из jcmd
доступных в jcmd
, доступны только тогда, когда диагностические операции разблокированы с -XX: + UnlockDiagnosticVMOptions (указывается при запуске процесса Java). Это верно для аналогов DiagnosticCommandMBean
как показано в следующем листинге кода и в листинге вывода.
Доступ к статистике классов
01
02
03
04
05
06
07
08
09
10
11
|
/** * 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" ); } |
1
|
GC.class_stats command requires -XX:+UnlockDiagnosticVMOptions |
Одна подкоманда jcmd
я не видел в качестве операции над DiagnosticCommandMBean
— это генерация дампа кучи ( jcmd
GC.heap_dump
). Насколько я могу судить, нет никакой эквивалентной операции, предоставляемой DiagnosticCommandMBean
по просмотру представленных операций в VisualVM и JConsole и по доступным командам, перечисленным в операции «help», как показано выше. Хотя DiagnosticCommandMBean
, по-видимому, не обеспечивает операцию для вызова дампа кучи, другой MBean ( com.sun.management.HotSpotDiagnostic с ObjectName из «com.sun.management:type=HotSpotDiagnostic») работает с операцией «dumpHeap», и это продемонстрировано в блоге А. Сундараджана « Программный сброс кучи из приложений Java ».
Вывод
DiagnosticCommandMBean
предоставляет большую часть функциональности jcmd и поэтому делает функциональность jcmd доступной для приложений Java для запуска этих функций против себя.
Списки кода, показанные в этом посте, доступны в классе VirtualMachineDiagnostics
, который доступен на GitHub . Я могу добавить или изменить этот класс в будущем, но исходная версия имеет такой же код, как показано в этом посте.
Ссылка: | Programmatic jcmd Доступ от нашего партнера JCG Дастина Маркса в блоге Inspired by Actual Events . |