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