1 /*
  2  * Copyright (c) 2003, 2024, 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 jdk.internal.perf.Perf;
 29 import sun.management.counter.*;
 30 import sun.management.counter.perf.*;
 31 import java.nio.ByteBuffer;
 32 import java.io.IOException;
 33 import java.net.InetAddress;
 34 import java.net.UnknownHostException;
 35 import java.util.List;
 36 import java.util.Arrays;
 37 import java.util.Collections;
 38 
 39 /**
 40  * Implementation of VMManagement interface that accesses the management
 41  * attributes and operations locally within the same Java virtual
 42  * machine.
 43  */
 44 class VMManagementImpl implements VMManagement {
 45 
 46     private static String version;
 47 
 48     private static boolean compTimeMonitoringSupport;
 49     private static boolean threadContentionMonitoringSupport;
 50     private static boolean currentThreadCpuTimeSupport;
 51     private static boolean otherThreadCpuTimeSupport;
 52     private static boolean objectMonitorUsageSupport;
 53     private static boolean synchronizerUsageSupport;
 54     private static boolean threadAllocatedMemorySupport;
 55     private static boolean gcNotificationSupport;
 56     private static boolean remoteDiagnosticCommandsSupport;
 57 
 58 
 59     static {
 60         version = getVersion0();
 61         if (version == null) {
 62             throw new AssertionError("Invalid Management Version");
 63         }
 64         initOptionalSupportFields();
 65     }
 66     private static native String getVersion0();
 67     private static native void initOptionalSupportFields();
 68 
 69     // Optional supports
 70     public boolean isCompilationTimeMonitoringSupported() {
 71         return compTimeMonitoringSupport;
 72     }
 73 
 74     public boolean isThreadContentionMonitoringSupported() {
 75         return threadContentionMonitoringSupport;
 76     }
 77 
 78     public boolean isCurrentThreadCpuTimeSupported() {
 79         return currentThreadCpuTimeSupport;
 80     }
 81 
 82     public boolean isOtherThreadCpuTimeSupported() {
 83         return otherThreadCpuTimeSupport;
 84     }
 85 
 86     public boolean isBootClassPathSupported() {
 87         return false;
 88     }
 89 
 90     public boolean isObjectMonitorUsageSupported() {
 91         return objectMonitorUsageSupport;
 92     }
 93 
 94     public boolean isSynchronizerUsageSupported() {
 95         return synchronizerUsageSupport;
 96     }
 97 
 98     public boolean isThreadAllocatedMemorySupported() {
 99         return threadAllocatedMemorySupport;
100     }
101 
102     public boolean isGcNotificationSupported() {
103         boolean isSupported = true;
104         try {
105             Class.forName("com.sun.management.GarbageCollectorMXBean");
106         } catch (ClassNotFoundException x) {
107             isSupported = false;
108         }
109         return isSupported;
110     }
111 
112     public boolean isRemoteDiagnosticCommandsSupported() {
113         return remoteDiagnosticCommandsSupport;
114     }
115 
116     public native boolean isThreadContentionMonitoringEnabled();
117     public native boolean isThreadCpuTimeEnabled();
118     public native boolean isThreadAllocatedMemoryEnabled();
119 
120     // Class Loading Subsystem
121     public int    getLoadedClassCount() {
122         long count = getTotalClassCount() - getUnloadedClassCount();
123         return (int) count;
124     }
125     public native long getTotalClassCount();
126     public native long getUnloadedClassCount();
127 
128     public native boolean getVerboseClass();
129 
130     // Memory Subsystem
131     public native boolean getVerboseGC();
132 
133     // Runtime Subsystem
134     public String   getManagementVersion() {
135         return version;
136     }
137 
138     public String getVmId() {
139         int pid = getProcessId();
140         String hostname = "localhost";
141         try {
142             hostname = InetAddress.getLocalHost().getHostName();
143         } catch (UnknownHostException e) {
144             // ignore
145         }
146 
147         return pid + "@" + hostname;
148     }
149     private native int getProcessId();
150 
151     public String   getVmName() {
152         return System.getProperty("java.vm.name");
153     }
154 
155     public String   getVmVendor() {
156         return System.getProperty("java.vm.vendor");
157     }
158     public String   getVmVersion() {
159         return System.getProperty("java.vm.version");
160     }
161     public String   getVmSpecName()  {
162         return System.getProperty("java.vm.specification.name");
163     }
164     public String   getVmSpecVendor() {
165         return System.getProperty("java.vm.specification.vendor");
166     }
167     public String   getVmSpecVersion() {
168         return System.getProperty("java.vm.specification.version");
169     }
170     public String   getClassPath() {
171         return System.getProperty("java.class.path");
172     }
173     public String   getLibraryPath()  {
174         return System.getProperty("java.library.path");
175     }
176 
177     public String   getBootClassPath( ) {
178         throw new UnsupportedOperationException(
179             "Boot class path mechanism is not supported");
180     }
181 
182     public long getUptime() {
183         return getUptime0();
184     }
185 
186     private List<String> vmArgs = null;
187     public synchronized List<String> getVmArguments() {
188         if (vmArgs == null) {
189             String[] args = getVmArguments0();
190             List<String> l = ((args != null && args.length != 0) ? Arrays.asList(args) :
191                                         Collections.<String>emptyList());
192             vmArgs = Collections.unmodifiableList(l);
193         }
194         return vmArgs;
195     }
196     public native String[] getVmArguments0();
197 
198     public native long getStartupTime();
199     private native long getUptime0();
200     public native int getAvailableProcessors();
201 
202     // Compilation Subsystem
203     public String getCompilerName() {
204         return System.getProperty("sun.management.compiler");
205     }
206     public native long getTotalCompileTime();
207 
208     // Thread Subsystem
209     public native long getTotalThreadCount();
210     public native int  getLiveThreadCount();
211     public native int  getPeakThreadCount();
212     public native int  getDaemonThreadCount();
213 
214     // Operating System
215     public String getOsName() {
216         return System.getProperty("os.name");
217     }
218     public String getOsArch() {
219         return System.getProperty("os.arch");
220     }
221     public String getOsVersion() {
222         return System.getProperty("os.version");
223     }
224 
225     // Hotspot-specific runtime support
226     public native long getSafepointCount();
227     public native long getTotalSafepointTime();
228     public native long getSafepointSyncTime();
229     public native long getTotalApplicationNonStoppedTime();
230 
231     public native long getLoadedClassSize();
232     public native long getUnloadedClassSize();
233     public native long getClassLoadingTime();
234     public native long getMethodDataSize();
235     public native long getInitializedClassCount();
236     public native long getClassInitializationTime();
237     public native long getClassVerificationTime();
238 
239     // Performance Counter Support
240     private PerfInstrumentation perfInstr = null;
241     private boolean noPerfData = false;
242 
243     private synchronized PerfInstrumentation getPerfInstrumentation() {
244         if (noPerfData || perfInstr != null) {
245              return perfInstr;
246         }
247 
248         // construct PerfInstrumentation object
249         Perf perf = Perf.getPerf();
250         try {
251             ByteBuffer bb = perf.attach(0);
252             if (bb.capacity() == 0) {
253                 noPerfData = true;
254                 return null;
255             }
256             perfInstr = new PerfInstrumentation(bb);
257         } catch (IllegalArgumentException e) {
258             // If the shared memory doesn't exist e.g. if -XX:-UsePerfData
259             // was set
260             noPerfData = true;
261         } catch (IOException e) {
262             throw new AssertionError(e);
263         }
264         return perfInstr;
265     }
266 
267     public List<Counter> getInternalCounters(String pattern) {
268         PerfInstrumentation perf = getPerfInstrumentation();
269         if (perf != null) {
270             return perf.findByPattern(pattern);
271         } else {
272             return Collections.emptyList();
273         }
274     }
275 }