Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.management/share/classes/sun/management/ManagementFactoryHelper.java
41152 views
1
/*
2
* Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle in the LICENSE file that accompanied this code.
10
*
11
* This code is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* version 2 for more details (a copy is included in the LICENSE file that
15
* accompanied this code).
16
*
17
* You should have received a copy of the GNU General Public License version
18
* 2 along with this work; if not, write to the Free Software Foundation,
19
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
*
21
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
23
* questions.
24
*/
25
26
package sun.management;
27
28
import java.lang.invoke.MethodHandles;
29
import java.lang.management.*;
30
import java.lang.reflect.InvocationTargetException;
31
import java.lang.reflect.Method;
32
import javax.management.InstanceAlreadyExistsException;
33
import javax.management.InstanceNotFoundException;
34
import javax.management.MBeanServer;
35
import javax.management.MBeanRegistrationException;
36
import javax.management.NotCompliantMBeanException;
37
import javax.management.ObjectName;
38
import javax.management.RuntimeOperationsException;
39
import java.security.AccessController;
40
import java.security.PrivilegedActionException;
41
import java.security.PrivilegedExceptionAction;
42
43
import jdk.internal.misc.VM;
44
import jdk.internal.misc.VM.BufferPool;
45
46
import java.util.ArrayList;
47
import java.util.List;
48
49
import java.lang.reflect.UndeclaredThrowableException;
50
import java.security.PrivilegedAction;
51
import java.util.Arrays;
52
import java.util.Collections;
53
import java.util.HashMap;
54
import java.util.Map;
55
import java.util.Optional;
56
import java.util.stream.Collectors;
57
58
/**
59
* ManagementFactoryHelper provides static factory methods to create
60
* instances of the management interface.
61
*/
62
public class ManagementFactoryHelper {
63
static {
64
// make sure that the management lib is loaded within
65
// java.lang.management.ManagementFactory
66
try {
67
MethodHandles.lookup().ensureInitialized(ManagementFactory.class);
68
} catch (IllegalAccessException e) {}
69
}
70
71
private static final VMManagement jvm = new VMManagementImpl();
72
73
private ManagementFactoryHelper() {};
74
75
public static VMManagement getVMManagement() {
76
return jvm;
77
}
78
79
static final String LOGGING_MXBEAN_NAME = "java.util.logging:type=Logging";
80
private static ClassLoadingImpl classMBean = null;
81
private static MemoryImpl memoryMBean = null;
82
private static ThreadImpl threadMBean = null;
83
private static RuntimeImpl runtimeMBean = null;
84
private static CompilationImpl compileMBean = null;
85
private static BaseOperatingSystemImpl osMBean = null;
86
87
public static synchronized ClassLoadingMXBean getClassLoadingMXBean() {
88
if (classMBean == null) {
89
classMBean = new ClassLoadingImpl(jvm);
90
}
91
return classMBean;
92
}
93
94
public static synchronized MemoryMXBean getMemoryMXBean() {
95
if (memoryMBean == null) {
96
memoryMBean = new MemoryImpl(jvm);
97
}
98
return memoryMBean;
99
}
100
101
public static synchronized ThreadMXBean getThreadMXBean() {
102
if (threadMBean == null) {
103
threadMBean = new ThreadImpl(jvm);
104
}
105
return threadMBean;
106
}
107
108
public static synchronized RuntimeMXBean getRuntimeMXBean() {
109
if (runtimeMBean == null) {
110
runtimeMBean = new RuntimeImpl(jvm);
111
}
112
return runtimeMBean;
113
}
114
115
public static synchronized CompilationMXBean getCompilationMXBean() {
116
if (compileMBean == null && jvm.getCompilerName() != null) {
117
compileMBean = new CompilationImpl(jvm);
118
}
119
return compileMBean;
120
}
121
122
public static synchronized OperatingSystemMXBean getOperatingSystemMXBean() {
123
if (osMBean == null) {
124
osMBean = new BaseOperatingSystemImpl(jvm);
125
}
126
return osMBean;
127
}
128
129
public static List<MemoryPoolMXBean> getMemoryPoolMXBeans() {
130
MemoryPoolMXBean[] pools = MemoryImpl.getMemoryPools();
131
List<MemoryPoolMXBean> list = new ArrayList<>(pools.length);
132
for (MemoryPoolMXBean p : pools) {
133
list.add(p);
134
}
135
return list;
136
}
137
138
public static List<MemoryManagerMXBean> getMemoryManagerMXBeans() {
139
MemoryManagerMXBean[] mgrs = MemoryImpl.getMemoryManagers();
140
List<MemoryManagerMXBean> result = new ArrayList<>(mgrs.length);
141
for (MemoryManagerMXBean m : mgrs) {
142
result.add(m);
143
}
144
return result;
145
}
146
147
public static List<GarbageCollectorMXBean> getGarbageCollectorMXBeans() {
148
MemoryManagerMXBean[] mgrs = MemoryImpl.getMemoryManagers();
149
List<GarbageCollectorMXBean> result = new ArrayList<>(mgrs.length);
150
for (MemoryManagerMXBean m : mgrs) {
151
if (GarbageCollectorMXBean.class.isInstance(m)) {
152
result.add(GarbageCollectorMXBean.class.cast(m));
153
}
154
}
155
return result;
156
}
157
158
public static PlatformLoggingMXBean getPlatformLoggingMXBean() {
159
if (LoggingMXBeanAccess.isAvailable()) {
160
return PlatformLoggingImpl.MBEAN;
161
} else {
162
return null;
163
}
164
}
165
166
public static boolean isPlatformLoggingMXBeanAvailable() {
167
return LoggingMXBeanAccess.isAvailable();
168
}
169
170
/**
171
* Returns an array of the name of all memory pools. The order of the memory pools is
172
* significant and maintained in the VM.
173
*/
174
public static String[] getAllMemoryPoolNames() {
175
return Arrays.stream(MemoryImpl.getMemoryPools())
176
.map(MemoryPoolMXBean::getName)
177
.toArray(String[]::new);
178
}
179
180
// The LoggingMXBeanAccess class uses reflection to determine
181
// whether java.util.logging is present, and load the actual LoggingMXBean
182
// implementation.
183
//
184
static final class LoggingMXBeanAccess {
185
186
static final String LOG_MANAGER_CLASS_NAME = "java.util.logging.LogManager";
187
static final String LOGGING_MXBEAN_CLASS_NAME = "java.util.logging.LoggingMXBean";
188
static final Class<?> LOG_MANAGER_CLASS = loadLoggingClass(LOG_MANAGER_CLASS_NAME);
189
190
static boolean isAvailable() {
191
return LOG_MANAGER_CLASS != null;
192
}
193
194
@SuppressWarnings("removal")
195
private static Class<?> loadLoggingClass(String className) {
196
return AccessController.doPrivileged(new PrivilegedAction<>() {
197
@Override
198
public Class<?> run() {
199
Optional<Module> logging = ModuleLayer.boot().findModule("java.logging");
200
if (logging.isPresent()) {
201
return Class.forName(logging.get(), className);
202
}
203
return null;
204
}
205
});
206
}
207
208
private Map<String, Method> initMethodMap(Object impl) {
209
if (impl == null) {
210
return Collections.emptyMap();
211
}
212
Class<?> intfClass = loadLoggingClass(LOGGING_MXBEAN_CLASS_NAME);
213
final Map<String, Method> methodsMap = new HashMap<>();
214
for (Method m : intfClass.getMethods()) {
215
try {
216
// Sanity checking: all public methods present in
217
// java.util.logging.LoggingMXBean should
218
// also be in PlatformLoggingMXBean
219
Method specMethod = PlatformLoggingMXBean.class
220
.getMethod(m.getName(), m.getParameterTypes());
221
if (specMethod.getReturnType().isAssignableFrom(m.getReturnType())) {
222
if (methodsMap.putIfAbsent(m.getName(), m) != null) {
223
throw new RuntimeException("unexpected polymorphic method: "
224
+ m.getName());
225
}
226
}
227
} catch (NoSuchMethodException x) {
228
// All methods in java.util.logging.LoggingMXBean should
229
// also be in PlatformLoggingMXBean
230
throw new InternalError(x);
231
}
232
}
233
return Collections.unmodifiableMap(methodsMap);
234
}
235
236
private static Object getMXBeanImplementation() {
237
if (!isAvailable()) {
238
// should not happen
239
throw new NoClassDefFoundError(LOG_MANAGER_CLASS_NAME);
240
}
241
try {
242
final Method m = LOG_MANAGER_CLASS.getMethod("getLoggingMXBean");
243
return m.invoke(null);
244
} catch (NoSuchMethodException
245
| IllegalAccessException
246
| InvocationTargetException x) {
247
throw new ExceptionInInitializerError(x);
248
}
249
}
250
251
// The implementation object, which will be invoked through
252
// reflection. The implementation does not need to implement
253
// PlatformLoggingMXBean, but must declare the same methods
254
// with same signatures, and they must be public, with one
255
// exception:
256
// getObjectName will not be called on the implementation object,
257
// so the implementation object does not need to declare such
258
// a method.
259
final Object impl = getMXBeanImplementation();
260
final Map<String, Method> methods = initMethodMap(impl);
261
262
LoggingMXBeanAccess() {
263
}
264
265
<T> T invoke(String methodName, Object... args) {
266
Method m = methods.get(methodName);
267
if (m == null) {
268
throw new UnsupportedOperationException(methodName);
269
}
270
try {
271
@SuppressWarnings("unchecked")
272
T result = (T) m.invoke(impl, args);
273
return result;
274
} catch (IllegalAccessException ex) {
275
throw new UnsupportedOperationException(ex);
276
} catch (InvocationTargetException ex) {
277
throw unwrap(ex);
278
}
279
}
280
281
private static RuntimeException unwrap(InvocationTargetException x) {
282
Throwable t = x.getCause();
283
if (t instanceof RuntimeException) {
284
return (RuntimeException)t;
285
}
286
if (t instanceof Error) {
287
throw (Error)t;
288
}
289
return new UndeclaredThrowableException(t == null ? x : t);
290
}
291
292
293
}
294
295
static final class PlatformLoggingImpl implements PlatformLoggingMXBean {
296
297
private final LoggingMXBeanAccess loggingAccess;
298
private PlatformLoggingImpl(LoggingMXBeanAccess loggingAccess) {
299
this.loggingAccess = loggingAccess;
300
}
301
302
private volatile ObjectName objname; // created lazily
303
@Override
304
public ObjectName getObjectName() {
305
ObjectName result = objname;
306
if (result == null) {
307
synchronized (this) {
308
result = objname;
309
if (result == null) {
310
result = Util.newObjectName(LOGGING_MXBEAN_NAME);
311
objname = result;
312
}
313
}
314
}
315
return result;
316
}
317
318
@Override
319
public java.util.List<String> getLoggerNames() {
320
return loggingAccess.invoke("getLoggerNames");
321
}
322
323
@Override
324
public String getLoggerLevel(String loggerName) {
325
return loggingAccess.invoke("getLoggerLevel", loggerName);
326
}
327
328
@Override
329
public void setLoggerLevel(String loggerName, String levelName) {
330
loggingAccess.invoke("setLoggerLevel", loggerName, levelName);
331
}
332
333
@Override
334
public String getParentLoggerName(String loggerName) {
335
return loggingAccess.invoke("getParentLoggerName", loggerName);
336
}
337
338
private static PlatformLoggingImpl getInstance() {
339
return new PlatformLoggingImpl(new LoggingMXBeanAccess());
340
}
341
342
static final PlatformLoggingMXBean MBEAN = getInstance();
343
}
344
345
private static volatile List<BufferPoolMXBean> bufferPools;
346
public static List<BufferPoolMXBean> getBufferPoolMXBeans() {
347
if (bufferPools == null) {
348
synchronized (ManagementFactoryHelper.class) {
349
if (bufferPools == null) {
350
bufferPools = VM.getBufferPools().stream()
351
.map(ManagementFactoryHelper::createBufferPoolMXBean)
352
.collect(Collectors.toList());
353
}
354
}
355
}
356
return bufferPools;
357
}
358
359
private static final String BUFFER_POOL_MXBEAN_NAME = "java.nio:type=BufferPool";
360
361
/**
362
* Creates management interface for the given buffer pool.
363
*/
364
private static BufferPoolMXBean
365
createBufferPoolMXBean(final BufferPool pool)
366
{
367
return new BufferPoolMXBean() {
368
private volatile ObjectName objname; // created lazily
369
@Override
370
public ObjectName getObjectName() {
371
ObjectName result = objname;
372
if (result == null) {
373
synchronized (this) {
374
result = objname;
375
if (result == null) {
376
result = Util.newObjectName(BUFFER_POOL_MXBEAN_NAME +
377
",name=" + pool.getName());
378
objname = result;
379
}
380
}
381
}
382
return result;
383
}
384
@Override
385
public String getName() {
386
return pool.getName();
387
}
388
@Override
389
public long getCount() {
390
return pool.getCount();
391
}
392
@Override
393
public long getTotalCapacity() {
394
return pool.getTotalCapacity();
395
}
396
@Override
397
public long getMemoryUsed() {
398
return pool.getMemoryUsed();
399
}
400
};
401
}
402
403
private static HotspotRuntime hsRuntimeMBean = null;
404
private static HotspotClassLoading hsClassMBean = null;
405
private static HotspotThread hsThreadMBean = null;
406
private static HotspotCompilation hsCompileMBean = null;
407
private static HotspotMemory hsMemoryMBean = null;
408
409
/**
410
* This method is for testing only.
411
*/
412
public static synchronized HotspotRuntimeMBean getHotspotRuntimeMBean() {
413
if (hsRuntimeMBean == null) {
414
hsRuntimeMBean = new HotspotRuntime(jvm);
415
}
416
return hsRuntimeMBean;
417
}
418
419
/**
420
* This method is for testing only.
421
*/
422
public static synchronized HotspotClassLoadingMBean getHotspotClassLoadingMBean() {
423
if (hsClassMBean == null) {
424
hsClassMBean = new HotspotClassLoading(jvm);
425
}
426
return hsClassMBean;
427
}
428
429
/**
430
* This method is for testing only.
431
*/
432
public static synchronized HotspotThreadMBean getHotspotThreadMBean() {
433
if (hsThreadMBean == null) {
434
hsThreadMBean = new HotspotThread(jvm);
435
}
436
return hsThreadMBean;
437
}
438
439
/**
440
* This method is for testing only.
441
*/
442
public static synchronized HotspotMemoryMBean getHotspotMemoryMBean() {
443
if (hsMemoryMBean == null) {
444
hsMemoryMBean = new HotspotMemory(jvm);
445
}
446
return hsMemoryMBean;
447
}
448
449
/**
450
* This method is for testing only.
451
*/
452
public static synchronized HotspotCompilationMBean getHotspotCompilationMBean() {
453
if (hsCompileMBean == null) {
454
hsCompileMBean = new HotspotCompilation(jvm);
455
}
456
return hsCompileMBean;
457
}
458
459
/**
460
* Registers a given MBean if not registered in the MBeanServer;
461
* otherwise, just return.
462
*/
463
@SuppressWarnings("removal")
464
private static void addMBean(MBeanServer mbs, Object mbean, String mbeanName) {
465
try {
466
final ObjectName objName = Util.newObjectName(mbeanName);
467
468
// inner class requires these fields to be final
469
final MBeanServer mbs0 = mbs;
470
final Object mbean0 = mbean;
471
AccessController.doPrivileged(new PrivilegedExceptionAction<Void>() {
472
public Void run() throws MBeanRegistrationException,
473
NotCompliantMBeanException {
474
try {
475
mbs0.registerMBean(mbean0, objName);
476
return null;
477
} catch (InstanceAlreadyExistsException e) {
478
// if an instance with the object name exists in
479
// the MBeanServer ignore the exception
480
}
481
return null;
482
}
483
});
484
} catch (PrivilegedActionException e) {
485
throw Util.newException(e.getException());
486
}
487
}
488
489
private static final String HOTSPOT_CLASS_LOADING_MBEAN_NAME =
490
"sun.management:type=HotspotClassLoading";
491
492
private static final String HOTSPOT_COMPILATION_MBEAN_NAME =
493
"sun.management:type=HotspotCompilation";
494
495
private static final String HOTSPOT_MEMORY_MBEAN_NAME =
496
"sun.management:type=HotspotMemory";
497
498
private static final String HOTSPOT_RUNTIME_MBEAN_NAME =
499
"sun.management:type=HotspotRuntime";
500
501
private static final String HOTSPOT_THREAD_MBEAN_NAME =
502
"sun.management:type=HotspotThreading";
503
504
static void registerInternalMBeans(MBeanServer mbs) {
505
// register all internal MBeans if not registered
506
// No exception is thrown if a MBean with that object name
507
// already registered
508
addMBean(mbs, getHotspotClassLoadingMBean(),
509
HOTSPOT_CLASS_LOADING_MBEAN_NAME);
510
addMBean(mbs, getHotspotMemoryMBean(),
511
HOTSPOT_MEMORY_MBEAN_NAME);
512
addMBean(mbs, getHotspotRuntimeMBean(),
513
HOTSPOT_RUNTIME_MBEAN_NAME);
514
addMBean(mbs, getHotspotThreadMBean(),
515
HOTSPOT_THREAD_MBEAN_NAME);
516
517
// CompilationMBean may not exist
518
if (getCompilationMXBean() != null) {
519
addMBean(mbs, getHotspotCompilationMBean(),
520
HOTSPOT_COMPILATION_MBEAN_NAME);
521
}
522
}
523
524
@SuppressWarnings("removal")
525
private static void unregisterMBean(MBeanServer mbs, String mbeanName) {
526
try {
527
final ObjectName objName = Util.newObjectName(mbeanName);
528
529
// inner class requires these fields to be final
530
final MBeanServer mbs0 = mbs;
531
AccessController.doPrivileged(new PrivilegedExceptionAction<Void>() {
532
public Void run() throws MBeanRegistrationException,
533
RuntimeOperationsException {
534
try {
535
mbs0.unregisterMBean(objName);
536
} catch (InstanceNotFoundException e) {
537
// ignore exception if not found
538
}
539
return null;
540
}
541
});
542
} catch (PrivilegedActionException e) {
543
throw Util.newException(e.getException());
544
}
545
}
546
547
static void unregisterInternalMBeans(MBeanServer mbs) {
548
// unregister all internal MBeans
549
unregisterMBean(mbs, HOTSPOT_CLASS_LOADING_MBEAN_NAME);
550
unregisterMBean(mbs, HOTSPOT_MEMORY_MBEAN_NAME);
551
unregisterMBean(mbs, HOTSPOT_RUNTIME_MBEAN_NAME);
552
unregisterMBean(mbs, HOTSPOT_THREAD_MBEAN_NAME);
553
554
// CompilationMBean may not exist
555
if (getCompilationMXBean() != null) {
556
unregisterMBean(mbs, HOTSPOT_COMPILATION_MBEAN_NAME);
557
}
558
}
559
560
public static boolean isThreadSuspended(int state) {
561
return ((state & JMM_THREAD_STATE_FLAG_SUSPENDED) != 0);
562
}
563
564
public static boolean isThreadRunningNative(int state) {
565
return ((state & JMM_THREAD_STATE_FLAG_NATIVE) != 0);
566
}
567
568
public static Thread.State toThreadState(int state) {
569
// suspended and native bits may be set in state
570
int threadStatus = state & ~JMM_THREAD_STATE_FLAG_MASK;
571
return jdk.internal.misc.VM.toThreadState(threadStatus);
572
}
573
574
// These values are defined in jmm.h
575
private static final int JMM_THREAD_STATE_FLAG_MASK = 0xFFF00000;
576
private static final int JMM_THREAD_STATE_FLAG_SUSPENDED = 0x00100000;
577
private static final int JMM_THREAD_STATE_FLAG_NATIVE = 0x00400000;
578
579
// Invoked by the VM
580
private static MemoryPoolMXBean createMemoryPool
581
(String name, boolean isHeap, long uThreshold, long gcThreshold) {
582
return new MemoryPoolImpl(name, isHeap, uThreshold, gcThreshold);
583
}
584
585
private static MemoryManagerMXBean createMemoryManager(String name) {
586
return new MemoryManagerImpl(name);
587
}
588
589
private static GarbageCollectorMXBean
590
createGarbageCollector(String name, String type) {
591
592
// ignore type parameter which is for future extension
593
return new GarbageCollectorImpl(name);
594
}
595
}
596
597