Home | History | Annotate | Download | only in misc
      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
     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 asChange(int as_old, int as_new) { }
     98 
     99     /** @deprecated */
    100     @Deprecated
    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     //
    152     public static void booted() {
    153         booted = true;
    154     }
    155 
    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     //
    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.
    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     //
    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.
    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      */
    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.
    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.parseBoolean(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     //
    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      */
    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      */
    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      */
    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      */
    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