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