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 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 }