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