1 /* 2 * Copyright (c) 1996, 2010, 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 static java.lang.Thread.State.*; 29 import java.util.Properties; 30 import java.util.HashMap; 31 import java.util.Map; 32 import java.util.Set; 33 34 public class VM { 35 36 /* The following methods used to be native methods that instruct 37 * the VM to selectively suspend certain threads in low-memory 38 * situations. They are inherently dangerous and not implementable 39 * on native threads. We removed them in JDK 1.2. The skeletons 40 * remain so that existing applications that use these methods 41 * will still work. 42 */ 43 private static boolean suspended = false; 44 45 /** @deprecated */ 46 @Deprecated 47 public static boolean threadsSuspended() { 48 return suspended; 49 } 50 51 public static boolean allowThreadSuspension(ThreadGroup g, boolean b) { 52 return g.allowThreadSuspension(b); 53 } 54 55 /** @deprecated */ 56 @Deprecated 57 public static boolean suspendThreads() { 58 suspended = true; 59 return true; 60 } 61 62 // Causes any suspended threadgroups to be resumed. 63 /** @deprecated */ 64 @Deprecated 65 public static void unsuspendThreads() { 66 suspended = false; 67 } 68 69 // Causes threadgroups no longer marked suspendable to be resumed. 70 /** @deprecated */ 71 @Deprecated 72 public static void unsuspendSomeThreads() { 73 } 74 75 /* Deprecated fields and methods -- Memory advice not supported in 1.2 */ 76 77 /** @deprecated */ 78 @Deprecated 79 public static final int STATE_GREEN = 1; 80 81 /** @deprecated */ 82 @Deprecated 83 public static final int STATE_YELLOW = 2; 84 85 /** @deprecated */ 86 @Deprecated 87 public static final int STATE_RED = 3; 88 89 /** @deprecated */ 90 @Deprecated 91 public static final int getState() { 92 return STATE_GREEN; 93 } 94 95 /** @deprecated */ 96 @Deprecated 97 public static void registerVMNotification(VMNotification n) { } 98 99 /** @deprecated */ 100 @Deprecated 101 public static void asChange(int as_old, int as_new) { } 102 103 /** @deprecated */ 104 @Deprecated 105 public static void asChange_otherthread(int as_old, int as_new) { } 106 107 /* 108 * Not supported in 1.2 because these will have to be exported as 109 * JVM functions, and we are not sure we want do that. Leaving 110 * here so it can be easily resurrected -- just remove the // 111 * comments. 112 */ 113 114 /** 115 * Resume Java profiling. All profiling data is added to any 116 * earlier profiling, unless <code>resetJavaProfiler</code> is 117 * called in between. If profiling was not started from the 118 * command line, <code>resumeJavaProfiler</code> will start it. 119 * <p> 120 * 121 * NOTE: Profiling must be enabled from the command line for a 122 * java.prof report to be automatically generated on exit; if not, 123 * writeJavaProfilerReport must be invoked to write a report. 124 * 125 * @see resetJavaProfiler 126 * @see writeJavaProfilerReport 127 */ 128 129 // public native static void resumeJavaProfiler(); 130 131 /** 132 * Suspend Java profiling. 133 */ 134 // public native static void suspendJavaProfiler(); 135 136 /** 137 * Initialize Java profiling. Any accumulated profiling 138 * information is discarded. 139 */ 140 // public native static void resetJavaProfiler(); 141 142 /** 143 * Write the current profiling contents to the file "java.prof". 144 * If the file already exists, it will be overwritten. 145 */ 146 // public native static void writeJavaProfilerReport(); 147 148 149 private static volatile boolean booted = false; 150 151 // Invoked by by System.initializeSystemClass just before returning. 152 // Subsystems that are invoked during initialization can check this 153 // property in order to avoid doing things that should wait until the 154 // application class loader has been set up. 155 // 156 public static void booted() { 157 booted = true; 158 } 159 160 public static boolean isBooted() { 161 return booted; 162 } 163 164 // A user-settable upper limit on the maximum amount of allocatable direct 165 // buffer memory. This value may be changed during VM initialization if 166 // "java" is launched with "-XX:MaxDirectMemorySize=<size>". 167 // 168 // The initial value of this field is arbitrary; during JRE initialization 169 // it will be reset to the value specified on the command line, if any, 170 // otherwise to Runtime.getRuntime.maxDirectMemory(). 171 // 172 private static long directMemory = 64 * 1024 * 1024; 173 174 // Returns the maximum amount of allocatable direct buffer memory. 175 // The directMemory variable is initialized during system initialization 176 // in the saveAndRemoveProperties method. 177 // 178 public static long maxDirectMemory() { 179 return directMemory; 180 } 181 182 // User-controllable flag that determines if direct buffers should be page 183 // aligned. The "-XX:+PageAlignDirectMemory" option can be used to force 184 // buffers, allocated by ByteBuffer.allocateDirect, to be page aligned. 185 private static boolean pageAlignDirectMemory; 186 187 // Returns {@code true} if the direct buffers should be page aligned. This 188 // variable is initialized by saveAndRemoveProperties. 189 public static boolean isDirectMemoryPageAligned() { 190 return pageAlignDirectMemory; 191 } 192 193 // A user-settable boolean to determine whether ClassLoader.loadClass should 194 // accept array syntax. This value may be changed during VM initialization 195 // via the system property "sun.lang.ClassLoader.allowArraySyntax". 196 // 197 // The default for 1.5 is "true", array syntax is allowed. In 1.6, the 198 // default will be "false". The presence of this system property to 199 // control array syntax allows applications the ability to preview this new 200 // behaviour. 201 // 202 private static boolean defaultAllowArraySyntax = false; 203 private static boolean allowArraySyntax = defaultAllowArraySyntax; 204 205 // The allowArraySyntax boolean is initialized during system initialization 206 // in the saveAndRemoveProperties method. 207 // 208 // It is initialized based on the value of the system property 209 // "sun.lang.ClassLoader.allowArraySyntax". If the system property is not 210 // provided, the default for 1.5 is "true". In 1.6, the default will be 211 // "false". If the system property is provided, then the value of 212 // allowArraySyntax will be equal to "true" if Boolean.parseBoolean() 213 // returns "true". Otherwise, the field will be set to "false". 214 // 215 public static boolean allowArraySyntax() { 216 return allowArraySyntax; 217 } 218 219 /** 220 * Returns the system property of the specified key saved at 221 * system initialization time. This method should only be used 222 * for the system properties that are not changed during runtime. 223 * It accesses a private copy of the system properties so 224 * that user's locking of the system properties object will not 225 * cause the library to deadlock. 226 * 227 * Note that the saved system properties do not include 228 * the ones set by sun.misc.Version.init(). 229 * 230 */ 231 public static String getSavedProperty(String key) { 232 if (savedProps.isEmpty()) 233 throw new IllegalStateException("Should be non-empty if initialized"); 234 235 return savedProps.getProperty(key); 236 } 237 238 // TODO: the Property Management needs to be refactored and 239 // the appropriate prop keys need to be accessible to the 240 // calling classes to avoid duplication of keys. 241 private static final Properties savedProps = new Properties(); 242 243 // Save a private copy of the system properties and remove 244 // the system properties that are not intended for public access. 245 // 246 // This method can only be invoked during system initialization. 247 public static void saveAndRemoveProperties(Properties props) { 248 if (booted) 249 throw new IllegalStateException("System initialization has completed"); 250 251 savedProps.putAll(props); 252 253 // Set the maximum amount of direct memory. This value is controlled 254 // by the vm option -XX:MaxDirectMemorySize=<size>. 255 // The maximum amount of allocatable direct buffer memory (in bytes) 256 // from the system property sun.nio.MaxDirectMemorySize set by the VM. 257 // The system property will be removed. 258 String s = (String)props.remove("sun.nio.MaxDirectMemorySize"); 259 if (s != null) { 260 if (s.equals("-1")) { 261 // -XX:MaxDirectMemorySize not given, take default 262 directMemory = Runtime.getRuntime().maxMemory(); 263 } else { 264 long l = Long.parseLong(s); 265 if (l > -1) 266 directMemory = l; 267 } 268 } 269 270 // Check if direct buffers should be page aligned 271 s = (String)props.remove("sun.nio.PageAlignDirectMemory"); 272 if ("true".equals(s)) 273 pageAlignDirectMemory = true; 274 275 // Set a boolean to determine whether ClassLoader.loadClass accepts 276 // array syntax. This value is controlled by the system property 277 // "sun.lang.ClassLoader.allowArraySyntax". 278 s = props.getProperty("sun.lang.ClassLoader.allowArraySyntax"); 279 allowArraySyntax = (s == null 280 ? defaultAllowArraySyntax 281 : Boolean.parseBoolean(s)); 282 283 // Remove other private system properties 284 // used by java.lang.Integer.IntegerCache 285 props.remove("java.lang.Integer.IntegerCache.high"); 286 287 // used by java.util.zip.ZipFile 288 props.remove("sun.zip.disableMemoryMapping"); 289 290 // used by sun.launcher.LauncherHelper 291 props.remove("sun.java.launcher.diag"); 292 } 293 294 // Initialize any miscellenous operating system settings that need to be 295 // set for the class libraries. 296 // 297 public static void initializeOSEnvironment() { 298 if (!booted) { 299 OSEnvironment.initialize(); 300 } 301 } 302 303 /* Current count of objects pending for finalization */ 304 private static volatile int finalRefCount = 0; 305 306 /* Peak count of objects pending for finalization */ 307 private static volatile int peakFinalRefCount = 0; 308 309 /* 310 * Gets the number of objects pending for finalization. 311 * 312 * @return the number of objects pending for finalization. 313 */ 314 public static int getFinalRefCount() { 315 return finalRefCount; 316 } 317 318 /* 319 * Gets the peak number of objects pending for finalization. 320 * 321 * @return the peak number of objects pending for finalization. 322 */ 323 public static int getPeakFinalRefCount() { 324 return peakFinalRefCount; 325 } 326 327 /* 328 * Add <tt>n</tt> to the objects pending for finalization count. 329 * 330 * @param n an integer value to be added to the objects pending 331 * for finalization count 332 */ 333 public static void addFinalRefCount(int n) { 334 // The caller must hold lock to synchronize the update. 335 336 finalRefCount += n; 337 if (finalRefCount > peakFinalRefCount) { 338 peakFinalRefCount = finalRefCount; 339 } 340 } 341 342 /** 343 * Returns Thread.State for the given threadStatus 344 */ 345 public static Thread.State toThreadState(int threadStatus) { 346 if ((threadStatus & JVMTI_THREAD_STATE_RUNNABLE) != 0) { 347 return RUNNABLE; 348 } else if ((threadStatus & JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER) != 0) { 349 return BLOCKED; 350 } else if ((threadStatus & JVMTI_THREAD_STATE_WAITING_INDEFINITELY) != 0) { 351 return WAITING; 352 } else if ((threadStatus & JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT) != 0) { 353 return TIMED_WAITING; 354 } else if ((threadStatus & JVMTI_THREAD_STATE_TERMINATED) != 0) { 355 return TERMINATED; 356 } else if ((threadStatus & JVMTI_THREAD_STATE_ALIVE) == 0) { 357 return NEW; 358 } else { 359 return RUNNABLE; 360 } 361 } 362 363 /* The threadStatus field is set by the VM at state transition 364 * in the hotspot implementation. Its value is set according to 365 * the JVM TI specification GetThreadState function. 366 */ 367 private final static int JVMTI_THREAD_STATE_ALIVE = 0x0001; 368 private final static int JVMTI_THREAD_STATE_TERMINATED = 0x0002; 369 private final static int JVMTI_THREAD_STATE_RUNNABLE = 0x0004; 370 private final static int JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER = 0x0400; 371 private final static int JVMTI_THREAD_STATE_WAITING_INDEFINITELY = 0x0010; 372 private final static int JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT = 0x0020; 373 374 static { 375 initialize(); 376 } 377 private native static void initialize(); 378 }