1 /* 2 * Copyright (c) 2009, 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.misc; 27 28 import java.nio.ByteBuffer; 29 import java.nio.ByteOrder; 30 import java.nio.LongBuffer; 31 import java.security.AccessController; 32 33 /** 34 * Performance counter support for internal JRE classes. 35 * This class defines a fixed list of counters for the platform 36 * to use as an interim solution until RFE# 6209222 is implemented. 37 * The perf counters will be created in the jvmstat perf buffer 38 * that the HotSpot VM creates. The default size is 32K and thus 39 * the number of counters is bounded. You can alter the size 40 * with -XX:PerfDataMemorySize=<bytes> option. If there is 41 * insufficient memory in the jvmstat perf buffer, the C heap memory 42 * will be used and thus the application will continue to run if 43 * the counters added exceeds the buffer size but the counters 44 * will be missing. 45 * 46 * See HotSpot jvmstat implementation for certain circumstances 47 * that the jvmstat perf buffer is not supported. 48 * 49 */ 50 public class PerfCounter { 51 private static final Perf perf = 52 AccessController.doPrivileged(new Perf.GetPerfAction()); 53 54 // Must match values defined in hotspot/src/share/vm/runtime/perfdata.hpp 55 private final static int V_Constant = 1; 56 private final static int V_Monotonic = 2; 57 private final static int V_Variable = 3; 58 private final static int U_None = 1; 59 60 private final String name; 61 private final LongBuffer lb; 62 63 private PerfCounter(String name, int type) { 64 this.name = name; 65 ByteBuffer bb = perf.createLong(name, U_None, type, 0L); 66 bb.order(ByteOrder.nativeOrder()); 67 this.lb = bb.asLongBuffer(); 68 } 69 70 static PerfCounter newPerfCounter(String name) { 71 return new PerfCounter(name, V_Variable); 72 } 73 74 static PerfCounter newConstantPerfCounter(String name) { 75 PerfCounter c = new PerfCounter(name, V_Constant); 76 return c; 77 } 78 79 /** 80 * Returns the current value of the perf counter. 81 */ 82 public synchronized long get() { 83 return lb.get(0); 84 } 85 86 /** 87 * Sets the value of the perf counter to the given newValue. 88 */ 89 public synchronized void set(long newValue) { 90 lb.put(0, newValue); 91 } 92 93 /** 94 * Adds the given value to the perf counter. 95 */ 96 public synchronized void add(long value) { 97 long res = get() + value; 98 lb.put(0, res); 99 } 100 101 /** 102 * Increments the perf counter with 1. 103 */ 104 public void increment() { 105 add(1); 106 } 107 108 /** 109 * Adds the given interval to the perf counter. 110 */ 111 public void addTime(long interval) { 112 add(interval); 113 } 114 115 /** 116 * Adds the elapsed time from the given start time (ns) to the perf counter. 117 */ 118 public void addElapsedTimeFrom(long startTime) { 119 add(System.nanoTime() - startTime); 120 } 121 122 @Override 123 public String toString() { 124 return name + " = " + get(); 125 } 126 127 static class CoreCounters { 128 static final PerfCounter pdt = newPerfCounter("sun.classloader.parentDelegationTime"); 129 static final PerfCounter lc = newPerfCounter("sun.classloader.findClasses"); 130 static final PerfCounter lct = newPerfCounter("sun.classloader.findClassTime"); 131 static final PerfCounter rcbt = newPerfCounter("sun.urlClassLoader.readClassBytesTime"); 132 static final PerfCounter zfc = newPerfCounter("sun.zip.zipFiles"); 133 static final PerfCounter zfot = newPerfCounter("sun.zip.zipFile.openTime"); 134 } 135 136 static class WindowsClientCounters { 137 static final PerfCounter d3dAvailable = newConstantPerfCounter("sun.java2d.d3d.available"); 138 } 139 140 /** 141 * Number of findClass calls 142 */ 143 public static PerfCounter getFindClasses() { 144 return CoreCounters.lc; 145 } 146 147 /** 148 * Time (ns) spent in finding classes that includes 149 * lookup and read class bytes and defineClass 150 */ 151 public static PerfCounter getFindClassTime() { 152 return CoreCounters.lct; 153 } 154 155 /** 156 * Time (ns) spent in finding classes 157 */ 158 public static PerfCounter getReadClassBytesTime() { 159 return CoreCounters.rcbt; 160 } 161 162 /** 163 * Time (ns) spent in the parent delegation to 164 * the parent of the defining class loader 165 */ 166 public static PerfCounter getParentDelegationTime() { 167 return CoreCounters.pdt; 168 } 169 170 /** 171 * Number of zip files opened. 172 */ 173 public static PerfCounter getZipFileCount() { 174 return CoreCounters.zfc; 175 } 176 177 /** 178 * Time (ns) spent in opening the zip files that 179 * includes building the entries hash table 180 */ 181 public static PerfCounter getZipFileOpenTime() { 182 return CoreCounters.zfot; 183 } 184 185 /** 186 * D3D graphic pipeline available 187 */ 188 public static PerfCounter getD3DAvailable() { 189 return WindowsClientCounters.d3dAvailable; 190 } 191 }