diff options
Diffstat (limited to 'libjava/classpath/java/lang')
23 files changed, 4270 insertions, 22 deletions
diff --git a/libjava/classpath/java/lang/Iterable.java b/libjava/classpath/java/lang/Iterable.java index 8223bcf..35c4264 100644 --- a/libjava/classpath/java/lang/Iterable.java +++ b/libjava/classpath/java/lang/Iterable.java @@ -38,7 +38,8 @@ exception statement from your version. */ package java.lang; -import java.util.Iterator; +// We only need Iterator, but we import * to support lib/mkcollections.pl +import java.util.*; /** * This interface is used to indicate that a given class can be diff --git a/libjava/classpath/java/lang/SecurityManager.java b/libjava/classpath/java/lang/SecurityManager.java index 30ee1be..999fe83 100644 --- a/libjava/classpath/java/lang/SecurityManager.java +++ b/libjava/classpath/java/lang/SecurityManager.java @@ -421,7 +421,7 @@ public class SecurityManager public void checkAccess(Thread thread) { if (thread.getThreadGroup() != null - && thread.getThreadGroup().getParent() == null) + && thread.getThreadGroup().parent == null) checkPermission(new RuntimePermission("modifyThread")); } @@ -454,7 +454,7 @@ public class SecurityManager */ public void checkAccess(ThreadGroup g) { - if (g.getParent() == null) + if (g.parent == null) checkPermission(new RuntimePermission("modifyThreadGroup")); } diff --git a/libjava/classpath/java/lang/StrictMath.java b/libjava/classpath/java/lang/StrictMath.java index 548a6f1..0f06621 100644 --- a/libjava/classpath/java/lang/StrictMath.java +++ b/libjava/classpath/java/lang/StrictMath.java @@ -1,5 +1,5 @@ /* java.lang.StrictMath -- common mathematical functions, strict Java - Copyright (C) 1998, 2001, 2002, 2003 Free Software Foundation, Inc. + Copyright (C) 1998, 2001, 2002, 2003, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -633,6 +633,227 @@ public final strictfp class StrictMath } /** + * Returns the hyperbolic cosine of <code>x</code>, which is defined as + * (exp(x) + exp(-x)) / 2. + * + * Special cases: + * <ul> + * <li>If the argument is NaN, the result is NaN</li> + * <li>If the argument is positive infinity, the result is positive + * infinity.</li> + * <li>If the argument is negative infinity, the result is positive + * infinity.</li> + * <li>If the argument is zero, the result is one.</li> + * </ul> + * + * @param x the argument to <em>cosh</em> + * @return the hyperbolic cosine of <code>x</code> + * + * @since 1.5 + */ + public static double cosh(double x) + { + // Method : + // mathematically cosh(x) if defined to be (exp(x)+exp(-x))/2 + // 1. Replace x by |x| (cosh(x) = cosh(-x)). + // 2. + // [ exp(x) - 1 ]^2 + // 0 <= x <= ln2/2 : cosh(x) := 1 + ------------------- + // 2*exp(x) + // + // exp(x) + 1/exp(x) + // ln2/2 <= x <= 22 : cosh(x) := ------------------ + // 2 + // 22 <= x <= lnovft : cosh(x) := exp(x)/2 + // lnovft <= x <= ln2ovft: cosh(x) := exp(x/2)/2 * exp(x/2) + // ln2ovft < x : cosh(x) := +inf (overflow) + + double t, w; + long bits; + int hx; + int lx; + + // handle special cases + if (x != x) + return Double.NaN; + if (x == Double.POSITIVE_INFINITY) + return Double.POSITIVE_INFINITY; + if (x == Double.NEGATIVE_INFINITY) + return Double.POSITIVE_INFINITY; + + bits = Double.doubleToLongBits(x); + hx = getHighDWord(bits) & 0x7fffffff; // ignore sign + lx = getLowDWord(bits); + + // |x| in [0, 0.5 * ln(2)], return 1 + expm1(|x|)^2 / (2 * exp(|x|)) + if (hx < 0x3fd62e43) + { + t = expm1(abs(x)); + w = 1.0 + t; + + // for tiny arguments return 1. + if (hx < 0x3c800000) + return w; + + return 1.0 + (t * t) / (w + w); + } + + // |x| in [0.5 * ln(2), 22], return exp(|x|)/2 + 1 / (2 * exp(|x|)) + if (hx < 0x40360000) + { + t = exp(abs(x)); + + return 0.5 * t + 0.5 / t; + } + + // |x| in [22, log(Double.MAX_VALUE)], return 0.5 * exp(|x|) + if (hx < 0x40862e42) + return 0.5 * exp(abs(x)); + + // |x| in [log(Double.MAX_VALUE), overflowthreshold], + // return exp(x/2)/2 * exp(x/2) + + // we need to force an unsigned <= compare, thus can not use lx. + if ((hx < 0x408633ce) + || ((hx == 0x408633ce) + && ((bits & 0x00000000ffffffffL) <= 0x8fb9f87dL))) + { + w = exp(0.5 * abs(x)); + t = 0.5 * w; + + return t * w; + } + + // |x| > overflowthreshold + return Double.POSITIVE_INFINITY; + } + + /** + * Returns the lower two words of a long. This is intended to be + * used like this: + * <code>getLowDWord(Double.doubleToLongBits(x))</code>. + */ + private static int getLowDWord(long x) + { + return (int) (x & 0x00000000ffffffffL); + } + + /** + * Returns the higher two words of a long. This is intended to be + * used like this: + * <code>getHighDWord(Double.doubleToLongBits(x))</code>. + */ + private static int getHighDWord(long x) + { + return (int) ((x & 0xffffffff00000000L) >> 32); + } + + /** + * Returns a double with the IEEE754 bit pattern given in the lower + * and higher two words <code>lowDWord</code> and <code>highDWord</code>. + */ + private static double buildDouble(int lowDWord, int highDWord) + { + return Double.longBitsToDouble((((long) highDWord & 0xffffffffL) << 32) + | ((long) lowDWord & 0xffffffffL)); + } + + /** + * Returns the cube root of <code>x</code>. The sign of the cube root + * is equal to the sign of <code>x</code>. + * + * Special cases: + * <ul> + * <li>If the argument is NaN, the result is NaN</li> + * <li>If the argument is positive infinity, the result is positive + * infinity.</li> + * <li>If the argument is negative infinity, the result is negative + * infinity.</li> + * <li>If the argument is zero, the result is zero with the same + * sign as the argument.</li> + * </ul> + * + * @param x the number to take the cube root of + * @return the cube root of <code>x</code> + * @see #sqrt(double) + * + * @since 1.5 + */ + public static double cbrt(double x) + { + boolean negative = (x < 0); + double r; + double s; + double t; + double w; + + long bits; + int l; + int h; + + // handle the special cases + if (x != x) + return Double.NaN; + if (x == Double.POSITIVE_INFINITY) + return Double.POSITIVE_INFINITY; + if (x == Double.NEGATIVE_INFINITY) + return Double.NEGATIVE_INFINITY; + if (x == 0) + return x; + + x = abs(x); + bits = Double.doubleToLongBits(x); + + if (bits < 0x0010000000000000L) // subnormal number + { + t = TWO_54; + t *= x; + + // __HI(t)=__HI(t)/3+B2; + bits = Double.doubleToLongBits(t); + h = getHighDWord(bits); + l = getLowDWord(bits); + + h = h / 3 + CBRT_B2; + + t = buildDouble(l, h); + } + else + { + // __HI(t)=__HI(x)/3+B1; + h = getHighDWord(bits); + l = 0; + + h = h / 3 + CBRT_B1; + t = buildDouble(l, h); + } + + // new cbrt to 23 bits + r = t * t / x; + s = CBRT_C + r * t; + t *= CBRT_G + CBRT_F / (s + CBRT_E + CBRT_D / s); + + // chopped to 20 bits and make it larger than cbrt(x) + bits = Double.doubleToLongBits(t); + h = getHighDWord(bits); + + // __LO(t)=0; + // __HI(t)+=0x00000001; + l = 0; + h += 1; + t = buildDouble(l, h); + + // one step newton iteration to 53 bits with error less than 0.667 ulps + s = t * t; // t * t is exact + r = x / s; + w = t + t; + r = (r - t) / (w + r); // r - s is exact + t = t + t * r; + + return negative ? -t : t; + } + + /** * Take <em>e</em><sup>a</sup>. The opposite of <code>log()</code>. If the * argument is NaN, the result is NaN; if the argument is positive infinity, * the result is positive infinity; and if the argument is negative @@ -694,6 +915,254 @@ public final strictfp class StrictMath } /** + * Returns <em>e</em><sup>x</sup> - 1. + * Special cases: + * <ul> + * <li>If the argument is NaN, the result is NaN.</li> + * <li>If the argument is positive infinity, the result is positive + * infinity</li> + * <li>If the argument is negative infinity, the result is -1.</li> + * <li>If the argument is zero, the result is zero.</li> + * </ul> + * + * @param x the argument to <em>e</em><sup>x</sup> - 1. + * @return <em>e</em> raised to the power <code>x</code> minus one. + * @see #exp(double) + */ + public static double expm1(double x) + { + // Method + // 1. Argument reduction: + // Given x, find r and integer k such that + // + // x = k * ln(2) + r, |r| <= 0.5 * ln(2) + // + // Here a correction term c will be computed to compensate + // the error in r when rounded to a floating-point number. + // + // 2. Approximating expm1(r) by a special rational function on + // the interval [0, 0.5 * ln(2)]: + // Since + // r*(exp(r)+1)/(exp(r)-1) = 2 + r^2/6 - r^4/360 + ... + // we define R1(r*r) by + // r*(exp(r)+1)/(exp(r)-1) = 2 + r^2/6 * R1(r*r) + // That is, + // R1(r**2) = 6/r *((exp(r)+1)/(exp(r)-1) - 2/r) + // = 6/r * ( 1 + 2.0*(1/(exp(r)-1) - 1/r)) + // = 1 - r^2/60 + r^4/2520 - r^6/100800 + ... + // We use a special Remes algorithm on [0, 0.347] to generate + // a polynomial of degree 5 in r*r to approximate R1. The + // maximum error of this polynomial approximation is bounded + // by 2**-61. In other words, + // R1(z) ~ 1.0 + Q1*z + Q2*z**2 + Q3*z**3 + Q4*z**4 + Q5*z**5 + // where Q1 = -1.6666666666666567384E-2, + // Q2 = 3.9682539681370365873E-4, + // Q3 = -9.9206344733435987357E-6, + // Q4 = 2.5051361420808517002E-7, + // Q5 = -6.2843505682382617102E-9; + // (where z=r*r, and Q1 to Q5 are called EXPM1_Qx in the source) + // with error bounded by + // | 5 | -61 + // | 1.0+Q1*z+...+Q5*z - R1(z) | <= 2 + // | | + // + // expm1(r) = exp(r)-1 is then computed by the following + // specific way which minimize the accumulation rounding error: + // 2 3 + // r r [ 3 - (R1 + R1*r/2) ] + // expm1(r) = r + --- + --- * [--------------------] + // 2 2 [ 6 - r*(3 - R1*r/2) ] + // + // To compensate the error in the argument reduction, we use + // expm1(r+c) = expm1(r) + c + expm1(r)*c + // ~ expm1(r) + c + r*c + // Thus c+r*c will be added in as the correction terms for + // expm1(r+c). Now rearrange the term to avoid optimization + // screw up: + // ( 2 2 ) + // ({ ( r [ R1 - (3 - R1*r/2) ] ) } r ) + // expm1(r+c)~r - ({r*(--- * [--------------------]-c)-c} - --- ) + // ({ ( 2 [ 6 - r*(3 - R1*r/2) ] ) } 2 ) + // ( ) + // + // = r - E + // 3. Scale back to obtain expm1(x): + // From step 1, we have + // expm1(x) = either 2^k*[expm1(r)+1] - 1 + // = or 2^k*[expm1(r) + (1-2^-k)] + // 4. Implementation notes: + // (A). To save one multiplication, we scale the coefficient Qi + // to Qi*2^i, and replace z by (x^2)/2. + // (B). To achieve maximum accuracy, we compute expm1(x) by + // (i) if x < -56*ln2, return -1.0, (raise inexact if x!=inf) + // (ii) if k=0, return r-E + // (iii) if k=-1, return 0.5*(r-E)-0.5 + // (iv) if k=1 if r < -0.25, return 2*((r+0.5)- E) + // else return 1.0+2.0*(r-E); + // (v) if (k<-2||k>56) return 2^k(1-(E-r)) - 1 (or exp(x)-1) + // (vi) if k <= 20, return 2^k((1-2^-k)-(E-r)), else + // (vii) return 2^k(1-((E+2^-k)-r)) + + boolean negative = (x < 0); + double y, hi, lo, c, t, e, hxs, hfx, r1; + int k; + + long bits; + int h_bits; + int l_bits; + + c = 0.0; + y = abs(x); + + bits = Double.doubleToLongBits(y); + h_bits = getHighDWord(bits); + l_bits = getLowDWord(bits); + + // handle special cases and large arguments + if (h_bits >= 0x4043687a) // if |x| >= 56 * ln(2) + { + if (h_bits >= 0x40862e42) // if |x| >= EXP_LIMIT_H + { + if (h_bits >= 0x7ff00000) + { + if (((h_bits & 0x000fffff) | (l_bits & 0xffffffff)) != 0) + return Double.NaN; // exp(NaN) = NaN + else + return negative ? -1.0 : x; // exp({+-inf}) = {+inf, -1} + } + + if (x > EXP_LIMIT_H) + return Double.POSITIVE_INFINITY; // overflow + } + + if (negative) // x <= -56 * ln(2) + return -1.0; + } + + // argument reduction + if (h_bits > 0x3fd62e42) // |x| > 0.5 * ln(2) + { + if (h_bits < 0x3ff0a2b2) // |x| < 1.5 * ln(2) + { + if (negative) + { + hi = x + LN2_H; + lo = -LN2_L; + k = -1; + } + else + { + hi = x - LN2_H; + lo = LN2_L; + k = 1; + } + } + else + { + k = (int) (INV_LN2 * x + (negative ? - 0.5 : 0.5)); + t = k; + hi = x - t * LN2_H; + lo = t * LN2_L; + } + + x = hi - lo; + c = (hi - x) - lo; + + } + else if (h_bits < 0x3c900000) // |x| < 2^-54 return x + return x; + else + k = 0; + + // x is now in primary range + hfx = 0.5 * x; + hxs = x * hfx; + r1 = 1.0 + hxs * (EXPM1_Q1 + + hxs * (EXPM1_Q2 + + hxs * (EXPM1_Q3 + + hxs * (EXPM1_Q4 + + hxs * EXPM1_Q5)))); + t = 3.0 - r1 * hfx; + e = hxs * ((r1 - t) / (6.0 - x * t)); + + if (k == 0) + { + return x - (x * e - hxs); // c == 0 + } + else + { + e = x * (e - c) - c; + e -= hxs; + + if (k == -1) + return 0.5 * (x - e) - 0.5; + + if (k == 1) + { + if (x < - 0.25) + return -2.0 * (e - (x + 0.5)); + else + return 1.0 + 2.0 * (x - e); + } + + if (k <= -2 || k > 56) // sufficient to return exp(x) - 1 + { + y = 1.0 - (e - x); + + bits = Double.doubleToLongBits(y); + h_bits = getHighDWord(bits); + l_bits = getLowDWord(bits); + + h_bits += (k << 20); // add k to y's exponent + + y = buildDouble(l_bits, h_bits); + + return y - 1.0; + } + + t = 1.0; + if (k < 20) + { + bits = Double.doubleToLongBits(t); + h_bits = 0x3ff00000 - (0x00200000 >> k); + l_bits = getLowDWord(bits); + + t = buildDouble(l_bits, h_bits); // t = 1 - 2^(-k) + y = t - (e - x); + + bits = Double.doubleToLongBits(y); + h_bits = getHighDWord(bits); + l_bits = getLowDWord(bits); + + h_bits += (k << 20); // add k to y's exponent + + y = buildDouble(l_bits, h_bits); + } + else + { + bits = Double.doubleToLongBits(t); + h_bits = (0x000003ff - k) << 20; + l_bits = getLowDWord(bits); + + t = buildDouble(l_bits, h_bits); // t = 2^(-k) + + y = x - (e + t); + y += 1.0; + + bits = Double.doubleToLongBits(y); + h_bits = getHighDWord(bits); + l_bits = getLowDWord(bits); + + h_bits += (k << 20); // add k to y's exponent + + y = buildDouble(l_bits, h_bits); + } + } + + return y; + } + + /** * Take ln(a) (the natural log). The opposite of <code>exp()</code>. If the * argument is NaN or negative, the result is NaN; if the argument is * positive infinity, the result is positive infinity; and if the argument @@ -1429,6 +1898,33 @@ public final strictfp class StrictMath AT10 = 0.016285820115365782; // Long bits 0x3f90ad3ae322da11L. /** + * Constants for computing {@link #cbrt(double)}. + */ + private static final int + CBRT_B1 = 715094163, // B1 = (682-0.03306235651)*2**20 + CBRT_B2 = 696219795; // B2 = (664-0.03306235651)*2**20 + + /** + * Constants for computing {@link #cbrt(double)}. + */ + private static final double + CBRT_C = 5.42857142857142815906e-01, // Long bits 0x3fe15f15f15f15f1L + CBRT_D = -7.05306122448979611050e-01, // Long bits 0xbfe691de2532c834L + CBRT_E = 1.41428571428571436819e+00, // Long bits 0x3ff6a0ea0ea0ea0fL + CBRT_F = 1.60714285714285720630e+00, // Long bits 0x3ff9b6db6db6db6eL + CBRT_G = 3.57142857142857150787e-01; // Long bits 0x3fd6db6db6db6db7L + + /** + * Constants for computing {@link #expm1(double)} + */ + private static final double + EXPM1_Q1 = -3.33333333333331316428e-02, // Long bits 0xbfa11111111110f4L + EXPM1_Q2 = 1.58730158725481460165e-03, // Long bits 0x3f5a01a019fe5585L + EXPM1_Q3 = -7.93650757867487942473e-05, // Long bits 0xbf14ce199eaadbb7L + EXPM1_Q4 = 4.00821782732936239552e-06, // Long bits 0x3ed0cfca86e65239L + EXPM1_Q5 = -2.01099218183624371326e-07; // Long bits 0xbe8afdb76e09c32dL + + /** * Helper function for reducing an angle to a multiple of pi/2 within * [-pi/4, pi/4]. * diff --git a/libjava/classpath/java/lang/String.java b/libjava/classpath/java/lang/String.java index 199dfba..dbc3f7d 100644 --- a/libjava/classpath/java/lang/String.java +++ b/libjava/classpath/java/lang/String.java @@ -1820,7 +1820,7 @@ public final class String implements Serializable, Comparable, CharSequence */ public synchronized int codePointCount(int start, int end) { - if (start < 0 || end >= count || start > end) + if (start < 0 || end > count || start > end) throw new StringIndexOutOfBoundsException(); start += offset; diff --git a/libjava/classpath/java/lang/System.java b/libjava/classpath/java/lang/System.java index b538b79..19278aa 100644 --- a/libjava/classpath/java/lang/System.java +++ b/libjava/classpath/java/lang/System.java @@ -222,6 +222,36 @@ public final class System return VMSystem.currentTimeMillis(); } + /** + * <p> + * Returns the current value of a nanosecond-precise system timer. + * The value of the timer is an offset relative to some arbitrary fixed + * time, which may be in the future (making the value negative). This + * method is useful for timing events where nanosecond precision is + * required. This is achieved by calling this method before and after the + * event, and taking the difference betweent the two times: + * </p> + * <p> + * <code>long startTime = System.nanoTime();</code><br /> + * <code>... <emph>event code</emph> ...</code><br /> + * <code>long endTime = System.nanoTime();</code><br /> + * <code>long duration = endTime - startTime;</code><br /> + * </p> + * <p> + * Note that the value is only nanosecond-precise, and not accurate; there + * is no guarantee that the difference between two values is really a + * nanosecond. Also, the value is prone to overflow if the offset + * exceeds 2^63. + * </p> + * + * @return the time of a system timer in nanoseconds. + * @since 1.5 + */ + public static long nanoTime() + { + return VMSystem.nanoTime(); + } + /** * Copy one array onto another from <code>src[srcStart]</code> ... * <code>src[srcStart+len-1]</code> to <code>dest[destStart]</code> ... @@ -319,6 +349,7 @@ public final class System * <dt>gnu.java.io.encoding_scheme_alias.iso-latin-_?</dt> <dd>8859_?</dd> * <dt>gnu.java.io.encoding_scheme_alias.latin?</dt> <dd>8859_?</dd> * <dt>gnu.java.io.encoding_scheme_alias.utf-8</dt> <dd>UTF8</dd> + * <dt>gnu.javax.print.server</dt> <dd>Hostname of external CUPS server.</dd> * </dl> * * @return the system properties, will never be null diff --git a/libjava/classpath/java/lang/Thread.java b/libjava/classpath/java/lang/Thread.java index 2362054..36b7c33 100644 --- a/libjava/classpath/java/lang/Thread.java +++ b/libjava/classpath/java/lang/Thread.java @@ -38,8 +38,16 @@ exception statement from your version. */ package java.lang; +import gnu.classpath.VMStackWalker; import gnu.java.util.WeakIdentityHashMap; + +import java.lang.management.ManagementFactory; +import java.lang.management.ThreadInfo; +import java.lang.management.ThreadMXBean; + import java.security.Permission; + +import java.util.HashMap; import java.util.Map; /* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3 @@ -131,15 +139,16 @@ public class Thread implements Runnable /** The context classloader for this Thread. */ private ClassLoader contextClassLoader; - + private boolean contextClassLoaderIsSystemClassLoader; + /** This thread's ID. */ private final long threadId; /** The next thread number to use. */ private static int numAnonymousThreadsCreated; - /** The next thread ID to use. */ - private static long nextThreadId; + /** Used to generate the next thread ID to use. */ + private static long totalThreadsCreated; /** The default exception handler. */ private static UncaughtExceptionHandler defaultHandler; @@ -248,7 +257,7 @@ public class Thread implements Runnable */ public Thread(ThreadGroup group, Runnable target) { - this(group, target, "Thread-" + ++numAnonymousThreadsCreated, 0); + this(group, target, createAnonymousThreadName(), 0); } /** @@ -347,8 +356,8 @@ public class Thread implements Runnable if (group == null) group = current.group; } - else if (sm != null) - sm.checkAccess(group); + if (sm != null) + sm.checkAccess(group); this.group = group; // Use toString hack to detect null. @@ -358,12 +367,14 @@ public class Thread implements Runnable synchronized (Thread.class) { - this.threadId = nextThreadId++; + this.threadId = ++totalThreadsCreated; } priority = current.priority; daemon = current.daemon; contextClassLoader = current.contextClassLoader; + contextClassLoaderIsSystemClassLoader = + current.contextClassLoaderIsSystemClassLoader; group.addThread(this); InheritableThreadLocal.newChildThread(this); @@ -373,6 +384,9 @@ public class Thread implements Runnable * Used by the VM to create thread objects for threads started outside * of Java. Note: caller is responsible for adding the thread to * a group and InheritableThreadLocal. + * Note: This constructor should not call any methods that could result + * in a call to Thread.currentThread(), because that makes life harder + * for the VM. * * @param vmThread the native thread * @param name the thread name or null to use the default naming scheme @@ -384,16 +398,32 @@ public class Thread implements Runnable this.vmThread = vmThread; this.runnable = null; if (name == null) - name = "Thread-" + ++numAnonymousThreadsCreated; + name = createAnonymousThreadName(); this.name = name; this.priority = priority; this.daemon = daemon; - this.contextClassLoader = ClassLoader.getSystemClassLoader(); + // By default the context class loader is the system class loader, + // we set a flag to signal this because we don't want to call + // ClassLoader.getSystemClassLoader() at this point, because on + // VMs that lazily create the system class loader that might result + // in running user code (when a custom system class loader is specified) + // and that user code could call Thread.currentThread(). + // ClassLoader.getSystemClassLoader() can also return null, if the system + // is currently in the process of constructing the system class loader + // (and, as above, the constructiong sequence calls Thread.currenThread()). + contextClassLoaderIsSystemClassLoader = true; synchronized (Thread.class) { - this.threadId = nextThreadId++; + this.threadId = ++totalThreadsCreated; } + } + /** + * Generate a name for an anonymous thread. + */ + private static synchronized String createAnonymousThreadName() + { + return "Thread-" + ++numAnonymousThreadsCreated; } /** @@ -746,12 +776,18 @@ public class Thread implements Runnable */ public synchronized ClassLoader getContextClassLoader() { - // Bypass System.getSecurityManager, for bootstrap efficiency. + ClassLoader loader = contextClassLoaderIsSystemClassLoader ? + ClassLoader.getSystemClassLoader() : contextClassLoader; + // Check if we may get the classloader SecurityManager sm = SecurityManager.current; - if (sm != null) - // XXX Don't check this if the caller's class loader is an ancestor. - sm.checkPermission(new RuntimePermission("getClassLoader")); - return contextClassLoader; + if (loader != null && sm != null) + { + // Get the calling classloader + ClassLoader cl = VMStackWalker.getCallingClassLoader(); + if (cl != null && !cl.isAncestorOf(loader)) + sm.checkPermission(new RuntimePermission("getClassLoader")); + } + return loader; } /** @@ -772,6 +808,7 @@ public class Thread implements Runnable if (sm != null) sm.checkPermission(new RuntimePermission("setContextClassLoader")); this.contextClassLoader = classloader; + contextClassLoaderIsSystemClassLoader = false; } /** @@ -1173,7 +1210,7 @@ public class Thread implements Runnable * @author Andrew John Hughes <gnu_andrew@member.fsf.org> * @since 1.5 * @see Thread#getUncaughtExceptionHandler() - * @see Thread#setUncaughtExceptionHander(java.lang.Thread.UncaughtExceptionHandler) + * @see Thread#setUncaughtExceptionHandler(UncaughtExceptionHandler) * @see Thread#getDefaultUncaughtExceptionHandler() * @see * Thread#setDefaultUncaughtExceptionHandler(java.lang.Thread.UncaughtExceptionHandler) @@ -1191,4 +1228,119 @@ public class Thread implements Runnable */ void uncaughtException(Thread thr, Throwable exc); } + + /** + * Returns the current state of the thread. This + * is designed for monitoring thread behaviour, rather + * than for synchronization control. + * + * @return the current thread state. + */ + public String getState() + { + VMThread t = vmThread; + if (t != null) + return t.getState(); + if (group == null) + return "TERMINATED"; + return "NEW"; + } + + /** + * <p> + * Returns a map of threads to stack traces for each + * live thread. The keys of the map are {@link Thread} + * objects, which map to arrays of {@link StackTraceElement}s. + * The results obtained from Calling this method are + * equivalent to calling {@link getStackTrace()} on each + * thread in succession. Threads may be executing while + * this takes place, and the results represent a snapshot + * of the thread at the time its {@link getStackTrace()} + * method is called. + * </p> + * <p> + * The stack trace information contains the methods called + * by the thread, with the most recent method forming the + * first element in the array. The array will be empty + * if the virtual machine can not obtain information on the + * thread. + * </p> + * <p> + * To execute this method, the current security manager + * (if one exists) must allow both the + * <code>"getStackTrace"</code> and + * <code>"modifyThreadGroup"</code> {@link RuntimePermission}s. + * </p> + * + * @return a map of threads to arrays of {@link StackTraceElement}s. + * @throws SecurityException if a security manager exists, and + * prevents either or both the runtime + * permissions specified above. + * @since 1.5 + * @see #getStackTrace() + */ + public static Map getAllStackTraces() + { + ThreadGroup group = currentThread().group; + while (group.getParent() != null) + group = group.getParent(); + int arraySize = group.activeCount(); + Thread[] threadList = new Thread[arraySize]; + int filled = group.enumerate(threadList); + while (filled == arraySize) + { + arraySize *= 2; + threadList = new Thread[arraySize]; + filled = group.enumerate(threadList); + } + Map traces = new HashMap(); + for (int a = 0; a < filled; ++a) + traces.put(threadList[a], + threadList[a].getStackTrace()); + return traces; + } + + /** + * <p> + * Returns an array of {@link StackTraceElement}s + * representing the current stack trace of this thread. + * The first element of the array is the most recent + * method called, and represents the top of the stack. + * The elements continue in this order, with the last + * element representing the bottom of the stack. + * </p> + * <p> + * A zero element array is returned for threads which + * have not yet started (and thus have not yet executed + * any methods) or for those which have terminated. + * Where the virtual machine can not obtain a trace for + * the thread, an empty array is also returned. The + * virtual machine may also omit some methods from the + * trace in non-zero arrays. + * </p> + * <p> + * To execute this method, the current security manager + * (if one exists) must allow both the + * <code>"getStackTrace"</code> and + * <code>"modifyThreadGroup"</code> {@link RuntimePermission}s. + * </p> + * + * @return a stack trace for this thread. + * @throws SecurityException if a security manager exists, and + * prevents the use of the + * <code>"getStackTrace"</code> + * permission. + * @since 1.5 + * @see #getAllStackTraces() + */ + public StackTraceElement[] getStackTrace() + { + SecurityManager sm = SecurityManager.current; // Be thread-safe. + if (sm != null) + sm.checkPermission(new RuntimePermission("getStackTrace")); + ThreadMXBean bean = ManagementFactory.getThreadMXBean(); + ThreadInfo info = bean.getThreadInfo(threadId, Integer.MAX_VALUE); + return info.getStackTrace(); + } + } diff --git a/libjava/classpath/java/lang/ThreadGroup.java b/libjava/classpath/java/lang/ThreadGroup.java index 7fbef88..00f2f8e 100644 --- a/libjava/classpath/java/lang/ThreadGroup.java +++ b/libjava/classpath/java/lang/ThreadGroup.java @@ -66,7 +66,7 @@ public class ThreadGroup implements UncaughtExceptionHandler static boolean had_uncaught_exception; /** The parent thread group. */ - private final ThreadGroup parent; + final ThreadGroup parent; /** The group name, non-null. */ final String name; @@ -749,4 +749,43 @@ public class ThreadGroup implements UncaughtExceptionHandler parent.removeGroup(this); } } + + /* + * Helper method for the VM. Find a Thread by its Id. + * + * @param id The Thread Id. + * @return Thread object or null if thread doesn't exist. + */ + static Thread getThreadFromId(long id) + { + return root.getThreadFromIdImpl(id); + } + + private Thread getThreadFromIdImpl(long id) + { + synchronized (threads) + { + for (int i = 0; i < threads.size(); i++) + { + Thread t = (Thread) threads.get(i); + if (t.getId() == id) + return t; + } + } + Vector groups = this.groups; + if (groups != null) + { + synchronized (groups) + { + for (int i = 0; i < groups.size(); i++) + { + ThreadGroup g = (ThreadGroup) groups.get(i); + Thread t = g.getThreadFromIdImpl(id); + if (t != null) + return t; + } + } + } + return null; + } } // class ThreadGroup diff --git a/libjava/classpath/java/lang/annotation/IncompleteAnnotationException.java b/libjava/classpath/java/lang/annotation/IncompleteAnnotationException.java new file mode 100644 index 0000000..a35df0c --- /dev/null +++ b/libjava/classpath/java/lang/annotation/IncompleteAnnotationException.java @@ -0,0 +1,106 @@ +/* IncompleteAnnotationException.java - Thrown when annotation has changed + Copyright (C) 2004 Free Software Foundation + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package java.lang.annotation; + +/** + * Thrown when accessing an element within an annotation which + * was added since compilation or serialization took place, and + * does not have a default value. + * + * @author Tom Tromey (tromey@redhat.com) + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public class IncompleteAnnotationException extends RuntimeException +{ + + /** + * Constructs a new <code>IncompleteAnnotationException</code> + * which indicates that the element, <code>name</code>, was missing + * from the annotation, <code>type</code> at compile time and does + * not have a default value. + * + * @param type the type of annotation from which an element is missing. + * @param name the name of the missing element. + */ + public IncompleteAnnotationException(Class type, String name) + { + this.annotationType = type; + this.elementName = name; + } + + /** + * Returns the class representing the type of annotation + * from which an element was missing. + * + * @return the type of annotation. + */ + public Class annotationType() + { + return annotationType; + } + + /** + * Returns the name of the missing annotation element. + * + * @return the element name. + */ + public String elementName() + { + return elementName; + } + + // Names are chosen from serialization spec. + + /** + * The class representing the type of annotation from + * which an element was found to be missing. + * + * @serial the type of the annotation from which an + * element was missing. + */ + private Class annotationType; + + /** + * The name of the missing element. + * + * @serial the name of the missing element. + */ + private String elementName; + +} diff --git a/libjava/classpath/java/lang/management/ClassLoadingMXBean.java b/libjava/classpath/java/lang/management/ClassLoadingMXBean.java new file mode 100644 index 0000000..2a8651b --- /dev/null +++ b/libjava/classpath/java/lang/management/ClassLoadingMXBean.java @@ -0,0 +1,103 @@ +/* ClassLoadingMXBean.java - Interface for a class loading bean + Copyright (C) 2006 Free Software Foundation + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package java.lang.management; + +/** + * Provides access to information about the class loading + * behaviour of the current invocation of the virtual + * machine. An instance of this bean is obtained by calling + * {@link ManagementFactory#getClassLoadingMXBean()}. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public interface ClassLoadingMXBean +{ + + /** + * Returns the number of classes currently loaded by + * the virtual machine. + * + * @return the number of loaded classes. + */ + int getLoadedClassCount(); + + /** + * Returns the total number of classes loaded by the + * virtual machine since it was started. This is the + * sum of the currently loaded classes and those that + * have been unloaded. + * + * @return the total number of classes that have been + * loaded by the virtual machine since it started. + */ + long getTotalLoadedClassCount(); + + /** + * Returns the number of classes that have been unloaded + * by the virtual machine since it was started. + * + * @return the number of unloaded classes. + */ + long getUnloadedClassCount(); + + /** + * Returns true if the virtual machine will emit additional + * information when classes are loaded and unloaded. The + * format of the output is left up to the virtual machine. + * + * @return true if verbose class loading output is on. + */ + boolean isVerbose(); + + /** + * Turns on or off the emission of additional information + * when classes are loaded and unloaded. The format of the + * output is left up to the virtual machine. This method + * may be called by multiple threads concurrently, but there + * is only one global setting of verbosity that is affected. + * + * @param verbose the new setting for verbose class loading + * output. + * @throws SecurityException if a security manager exists and + * denies ManagementPermission("control"). + */ + void setVerbose(boolean verbose); + +} + diff --git a/libjava/classpath/java/lang/management/CompilationMXBean.java b/libjava/classpath/java/lang/management/CompilationMXBean.java new file mode 100644 index 0000000..7f666f2 --- /dev/null +++ b/libjava/classpath/java/lang/management/CompilationMXBean.java @@ -0,0 +1,85 @@ +/* CompilationMXBean.java - Interface for a compilation bean + Copyright (C) 2006 Free Software Foundation + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package java.lang.management; + +/** + * Provides access to information about the Just-In-Time + * (JIT) compiler provided by the virtual machine, if one + * exists. An instance of this bean is obtainable by + * calling {@link ManagementFactory#getCompilationMXBean()} + * if a JIT is available. Otherwise, the method returns + * <code>null</code>. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public interface CompilationMXBean +{ + + /** + * Returns the name of the Just-In-Time (JIT) compiler. + * + * @return the name of the JIT compiler. + */ + String getName(); + + /** + * Returns true if the virtual machine's JIT compiler + * supports monitoring of the time spent compiling. + * + * @return true if the JIT compiler can be monitored + * for time spent compiling. + */ + boolean isCompilationTimeMonitoringSupported(); + + /** + * Returns the accumulated time, in milliseconds, that + * the JIT compiler has spent compiling Java bytecodes + * to native machine code. This value represents a single + * time measurement for the whole virtual machine, including + * all multiple threads of operation. The value is not + * intended as a performance measurement. + * + * @return the accumulated number of milliseconds the JIT + * compiler has spent compiling. + * @throws UnsupportedOperationException if time monitoring + * is not supported. + */ + long getTotalCompilationTime(); + +} diff --git a/libjava/classpath/java/lang/management/GarbageCollectorMXBean.java b/libjava/classpath/java/lang/management/GarbageCollectorMXBean.java new file mode 100644 index 0000000..5bb0a18 --- /dev/null +++ b/libjava/classpath/java/lang/management/GarbageCollectorMXBean.java @@ -0,0 +1,79 @@ +/* GarbageCollectorMXBean.java - Interface for a garbage collector bean + Copyright (C) 2006 Free Software Foundation + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package java.lang.management; + +/** + * Provides access to information about the garbage collectors + * of the virtual machine. Garbage collectors are responsible + * for removing unreferenced objects from memory. A garbage + * collector is a type of memory manager, so this interface + * is combined with that of generic memory managers. An instance + * of this bean for each garbage collector is obtained by calling + * {@link ManagementFactory#getGarbageCollectorMXBeans()}. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public interface GarbageCollectorMXBean + extends MemoryManagerMXBean +{ + + /** + * Returns the number of collections the garbage collector + * represented by this bean has made. -1 is returned if the + * collection count is undefined. + * + * @return the number of collections made, or -1 if this is + * undefined. + */ + long getCollectionCount(); + + /** + * Returns the accumulated number of milliseconds this garbage + * collector has spent freeing the memory used by unreferenced + * objects. -1 is returned if the collection time is undefined. + * Note that the accumulated time may not change, even when the + * collection count increases, if the time taken is sufficiently + * short; this depends on the resolution of the timer used. + * + * @return the accumulated number of milliseconds spent collecting, + * or -1 if this is undefined. + */ + long getCollectionTime(); + +} diff --git a/libjava/classpath/java/lang/management/ManagementFactory.java b/libjava/classpath/java/lang/management/ManagementFactory.java new file mode 100644 index 0000000..6e7af0f --- /dev/null +++ b/libjava/classpath/java/lang/management/ManagementFactory.java @@ -0,0 +1,331 @@ +/* ManagementFactory.java - Factory for obtaining system beans. + Copyright (C) 2006 Free Software Foundation + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package java.lang.management; + +import gnu.classpath.SystemProperties; + +import gnu.java.lang.management.ClassLoadingMXBeanImpl; +import gnu.java.lang.management.CompilationMXBeanImpl; +import gnu.java.lang.management.GarbageCollectorMXBeanImpl; +import gnu.java.lang.management.OperatingSystemMXBeanImpl; +import gnu.java.lang.management.MemoryMXBeanImpl; +import gnu.java.lang.management.MemoryManagerMXBeanImpl; +import gnu.java.lang.management.MemoryPoolMXBeanImpl; +import gnu.java.lang.management.RuntimeMXBeanImpl; +import gnu.java.lang.management.ThreadMXBeanImpl; + +import java.util.ArrayList; +import java.util.List; + +import javax.management.NotCompliantMBeanException; + +/** + * <p> + * Provides access to the system's management beans via a series + * of static methods. + * </p> + * <p> + * An instance of a system management bean can be obtained by + * using one of the following methods: + * </p> + * <ol> + * <li>Calling the appropriate static method of this factory. + * </li> + * </ol> + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public class ManagementFactory +{ + + /** + * The operating system management bean. + */ + private static OperatingSystemMXBean osBean; + + /** + * The runtime management bean. + */ + private static RuntimeMXBean runtimeBean; + + /** + * The class loading management bean. + */ + private static ClassLoadingMXBean classLoadingBean; + + /** + * The thread bean. + */ + private static ThreadMXBean threadBean; + + /** + * The memory bean. + */ + private static MemoryMXBean memoryBean; + + /** + * The compilation bean (may remain null). + */ + private static CompilationMXBean compilationBean; + + /** + * Private constructor to prevent instance creation. + */ + private ManagementFactory() {} + + /** + * Returns the operating system management bean for the + * operating system on which the virtual machine is running. + * + * @return an instance of {@link OperatingSystemMXBean} for + * the underlying operating system. + */ + public static OperatingSystemMXBean getOperatingSystemMXBean() + { + if (osBean == null) + try + { + osBean = new OperatingSystemMXBeanImpl(); + } + catch (NotCompliantMBeanException e) + { + throw new InternalError("The GNU implementation of the " + + "operating system bean is not a " + + "compliant management bean."); + } + return osBean; + } + + /** + * Returns the runtime management bean for the + * running virtual machine. + * + * @return an instance of {@link RuntimeMXBean} for + * this virtual machine. + */ + public static RuntimeMXBean getRuntimeMXBean() + { + if (runtimeBean == null) + try + { + runtimeBean = new RuntimeMXBeanImpl(); + } + catch (NotCompliantMBeanException e) + { + throw new InternalError("The GNU implementation of the " + + "runtime bean is not a compliant " + + "management bean."); + } + return runtimeBean; + } + + /** + * Returns the class loading management bean for the + * running virtual machine. + * + * @return an instance of {@link ClassLoadingMXBean} for + * this virtual machine. + */ + public static ClassLoadingMXBean getClassLoadingMXBean() + { + if (classLoadingBean == null) + try + { + classLoadingBean = new ClassLoadingMXBeanImpl(); + } + catch (NotCompliantMBeanException e) + { + throw new InternalError("The GNU implementation of the " + + "class loading bean is not a " + + "compliant management bean."); + } + return classLoadingBean; + } + + /** + * Returns the thread management bean for the running + * virtual machine. + * + * @return an instance of {@link ThreadMXBean} for + * this virtual machine. + */ + public static ThreadMXBean getThreadMXBean() + { + if (threadBean == null) + try + { + threadBean = new ThreadMXBeanImpl(); + } + catch (NotCompliantMBeanException e) + { + throw new InternalError("The GNU implementation of the " + + "thread bean is not a compliant " + + "management bean."); + } + return threadBean; + } + + /** + * Returns the memory management bean for the running + * virtual machine. + * + * @return an instance of {@link MemoryMXBean} for + * this virtual machine. + */ + public static MemoryMXBean getMemoryMXBean() + { + if (memoryBean == null) + try + { + memoryBean = new MemoryMXBeanImpl(); + } + catch (NotCompliantMBeanException e) + { + throw new InternalError("The GNU implementation of the " + + "memory bean is not a compliant " + + "management bean."); + } + return memoryBean; + } + + /** + * Returns the compilation bean for the running + * virtual machine, if supported. Otherwise, + * it returns <code>null</code>. + * + * @return an instance of {@link CompilationMXBean} for + * this virtual machine, or <code>null</code> + * if the virtual machine doesn't include + * a Just-In-Time (JIT) compiler. + */ + public static CompilationMXBean getCompilationMXBean() + { + if (compilationBean == null && + SystemProperties.getProperty("gnu.java.compiler.name") != null) + try + { + compilationBean = new CompilationMXBeanImpl(); + } + catch (NotCompliantMBeanException e) + { + throw new InternalError("The GNU implementation of the " + + "compilation bean is not a compliant " + + "management bean."); + } + return compilationBean; + } + + /** + * Returns the memory pool beans for the running + * virtual machine. These may change during the course + * of execution. + * + * @return a list of memory pool beans, one for each pool. + */ + public static List getMemoryPoolMXBeans() + { + List poolBeans = new ArrayList(); + String[] names = VMManagementFactory.getMemoryPoolNames(); + for (int a = 0; a < names.length; ++a) + try + { + poolBeans.add(new MemoryPoolMXBeanImpl(names[a])); + } + catch (NotCompliantMBeanException e) + { + throw new InternalError("The GNU implementation of the " + + "memory pool bean, " + a + ", is " + + "not a compliant management bean."); + } + return poolBeans; + } + + /** + * Returns the memory manager beans for the running + * virtual machine. These may change during the course + * of execution. + * + * @return a list of memory manager beans, one for each manager. + */ + public static List getMemoryManagerMXBeans() + { + List managerBeans = new ArrayList(); + String[] names = VMManagementFactory.getMemoryManagerNames(); + for (int a = 0; a < names.length; ++a) + try + { + managerBeans.add(new MemoryManagerMXBeanImpl(names[a])); + } + catch (NotCompliantMBeanException e) + { + throw new InternalError("The GNU implementation of the " + + "memory manager bean, " + a + ", is " + + "not a compliant management bean."); + } + managerBeans.addAll(getGarbageCollectorMXBeans()); + return managerBeans; + } + + /** + * Returns the garbage collector beans for the running + * virtual machine. These may change during the course + * of execution. + * + * @return a list of garbage collector beans, one for each pool. + */ + public static List getGarbageCollectorMXBeans() + { + List gcBeans = new ArrayList(); + String[] names = VMManagementFactory.getGarbageCollectorNames(); + for (int a = 0; a < names.length; ++a) + try + { + gcBeans.add(new GarbageCollectorMXBeanImpl(names[a])); + } + catch (NotCompliantMBeanException e) + { + throw new InternalError("The GNU implementation of the " + + "garbage collector bean, " + a + + ", is not a compliant management " + + "bean."); + } + return gcBeans; + } + +} diff --git a/libjava/classpath/java/lang/management/ManagementPermission.java b/libjava/classpath/java/lang/management/ManagementPermission.java new file mode 100644 index 0000000..0e6bd06 --- /dev/null +++ b/libjava/classpath/java/lang/management/ManagementPermission.java @@ -0,0 +1,132 @@ +/* ManagementPermission.java - Permissions for system management. + Copyright (C) 2006 Free Software Foundation + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package java.lang.management; + +import java.security.BasicPermission; + +/** + * <p> + * Represents the permission to view or modify the data + * which forms part of the system management interfaces. + * Calls to methods of the system management beans, + * provided by the {@link ManagementFactory}, may perform + * checks against the current {@link java.lang.SecurityManager} + * (if any) before allowing the operation to proceed. + * Instances of this object are supplied to the + * {@link java.lang.SecurityManager} in order to perform + * these checks. It is not normal for instances of this + * class to be created outside the use of the + * {@link java.lang.SecurityManager}. + * </p> + * <p> + * This object can represent two types of management + * permission: + * </p> + * <ul> + * <li><strong>monitor</strong> — this allows access + * to information such as the arguments supplied to the + * virtual machine, the currently loaded classes and the + * stack traces of running threads. Malicious code may + * use this to obtain information about the system and + * exploit any vulnerabilities found.</li> + * <li><strong>control</strong> — this allows the + * information stored by the management beans to be altered. + * For example, additional debugging information (such + * as class loading traces) may be turned on or memory + * usage limits changed. Malicious code could use + * this to alter the behaviour of the system.</li> + * </ul> + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public final class ManagementPermission + extends BasicPermission +{ + + /** + * Compatible with JDK 1.5 + */ + private static final long serialVersionUID = 1897496590799378737L; + + /** + * Constructs a new <code>ManagementPermission</code> + * for one of the two permission targets, "monitor" + * and "control". + * + * @param name the name of the permission this instance + * should represent; either "monitor" or + * "control". + * @throws IllegalArgumentException if the name is not + * either "monitor" + * or "control". + */ + public ManagementPermission(String name) + { + super(name); + if (!(name.equals("monitor") || name.equals("control"))) + throw new IllegalArgumentException("Invalid permission."); + } + + /** + * Constructs a new <code>ManagementPermission</code> + * for one of the two permission targets, "monitor" + * and "control". Actions are not supported, so + * this value should be either <code>null</code> + * or the empty string. + * + * @param name the name of the permission this instance + * should represent; either "monitor" or + * "control". + * @param actions either <code>null</code> or the + * empty string. + * @throws IllegalArgumentException if the name is not + * either "monitor" + * or "control", or + * a value for actions + * is specified. + */ + public ManagementPermission(String name, String actions) + { + this(name); + if (!(actions == null || actions.equals(""))) + throw new IllegalArgumentException("Invalid actions."); + } + +} + diff --git a/libjava/classpath/java/lang/management/MemoryMXBean.java b/libjava/classpath/java/lang/management/MemoryMXBean.java new file mode 100644 index 0000000..4d9e5ff --- /dev/null +++ b/libjava/classpath/java/lang/management/MemoryMXBean.java @@ -0,0 +1,172 @@ +/* MemoryMXBean.java - Interface for a memory bean + Copyright (C) 2006 Free Software Foundation + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package java.lang.management; + +/** + * <p> + * Provides access to information about the memory used + * by the virtual machine. An instance of this bean is + * obtained by calling + * {@link ManagementFactory#getMemoryMXBean()}. + * </p> + * <p> + * The Java virtual machine uses two types of memory: + * heap memory and non-heap memory. The heap is the + * storage location for class and array instances, and is + * thus the main source of memory associated with running + * Java programs. The heap is created when the virtual + * machine is started, and is periodically scanned by the + * garbage collector(s), in order to reclaim memory which + * is no longer used (e.g. because an object reference has + * gone out of scope). + * </p> + * <p> + * Non-heap memory is used by the virtual machine in order to + * perform its duties. Thus, it mainly acts as the storage + * location for structures created as a result of parsing Java + * bytecode, such as the constant pool and constructor/method + * declarations. When a Just-In-Time (JIT) compiler is in + * operation, this will use non-heap memory to store compiled + * bytecode. + * </p> + * <p> + * Both types of memory may be non-contiguous. During the + * lifetime of the virtual machine, the size of both may + * either change (either expanding or contracting) or stay + * the same. + * </p> + * <h2>Notifications</h2> + * <p> + * Implementations of this interface also conform to the + * {@link javax.management.NotificationEmitter} interface, + * and supply two notifications reflecting memory usage. + * These notifications occur when a usage threshold is + * exceeded; for more details of these, see the documentation + * of {@link MemoryPoolMXBean}. If threshold monitoring + * is supported, then a notification will be emitted each time + * the threshold is crossed. Another notification will not + * be emitted unless the usage level has dropped below the + * threshold again in the meantime. + * </p> + * <p> + * The emitted notifications are instances of + * {@link javax.management.Notification}, with a type of + * either + * {@link java.lang.management.MemoryNotificationInfo#MEMORY_THRESHOLD_EXCEEDED} + * or + * {@link java.lang.management.MemoryNotificationInfo#MEMORY_COLLECTION_THRESHOLD_EXCEEDED} + * (depending on whether the notification refers to the general + * usage threshold or the garbage collection threshold) and an instance + * of {@link java.lang.management.MemoryNotificationInfo} contained + * in the user data section. This is wrapped inside an instance + * of {@link javax.management.openmbean.CompositeData}, as explained + * in the documentation for + * {@link java.lang.management.MemoryNotificationInfo}. + * </p> + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public interface MemoryMXBean +{ + + /** + * Instigates a garbage collection cycle. The virtual + * machine's garbage collector should make the best + * attempt it can at reclaiming unused memory. This + * is equivalent to invoking {@link java.lang.System.gc()}. + * + * @see java.lang.System#gc() + */ + void gc(); + + /** + * Returns a {@link MemoryUsage} object representing the + * current state of the heap. This incorporates various + * statistics on both the initial and current memory + * allocations used by the heap. + * + * @return a {@link MemoryUsage} object for the heap. + */ + MemoryUsage getHeapMemoryUsage(); + + /** + * Returns a {@link MemoryUsage} object representing the + * current state of non-heap memory. This incorporates + * various statistics on both the initial and current + * memory allocations used by non-heap memory.. + * + * @return a {@link MemoryUsage} object for non-heap + * memory. + */ + MemoryUsage getNonHeapMemoryUsage(); + + /** + * Returns the number of objects which are waiting to + * be garbage collected (finalized). An object is + * finalized when the garbage collector determines that + * there are no more references to that object are in + * use. + * + * @return the number of objects awaiting finalization. + */ + int getObjectPendingFinalizationCount(); + + /** + * Returns true if the virtual machine will emit additional + * information when memory is allocated and deallocated. The + * format of the output is left up to the virtual machine. + * + * @return true if verbose memory output is on. + */ + boolean isVerbose(); + + /** + * Turns on or off the emission of additional information + * when memory is allocated and deallocated. The format of the + * output is left up to the virtual machine. This method + * may be called by multiple threads concurrently, but there + * is only one global setting of verbosity that is affected. + * + * @param verbose the new setting for verbose memory output. + * @throws SecurityException if a security manager exists and + * denies ManagementPermission("control"). + */ + void setVerbose(boolean verbose); + +} diff --git a/libjava/classpath/java/lang/management/MemoryManagerMXBean.java b/libjava/classpath/java/lang/management/MemoryManagerMXBean.java new file mode 100644 index 0000000..9210705 --- /dev/null +++ b/libjava/classpath/java/lang/management/MemoryManagerMXBean.java @@ -0,0 +1,77 @@ +/* MemoryManagerMXBean.java - Interface for a memory manager bean + Copyright (C) 2006 Free Software Foundation + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package java.lang.management; + +/** + * Provides access to information about the memory managers + * of the virtual machine. An instance of this bean for each + * memory manager is obtained by calling + * {@link ManagementFactory#getMemoryManagerMXBeans()}. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public interface MemoryManagerMXBean +{ + + /** + * Returns an array containing the names of the memory pools + * this memory manager manages. + * + * @return an array containing the name of each memory pool + * this manager is responsible for. + */ + String[] getMemoryPoolNames(); + + /** + * Returns the name of the memory manager. + * + * @return the memory manager name. + */ + String getName(); + + /** + * Returns true if this memory manager is still valid. A memory + * manager becomes invalid when it is removed by the virtual machine + * and no longer used. + * + * @return true if this memory manager is valid. + */ + boolean isValid(); + +} diff --git a/libjava/classpath/java/lang/management/MemoryNotificationInfo.java b/libjava/classpath/java/lang/management/MemoryNotificationInfo.java new file mode 100644 index 0000000..adb38b0 --- /dev/null +++ b/libjava/classpath/java/lang/management/MemoryNotificationInfo.java @@ -0,0 +1,215 @@ +/* MemoryNotificationInfo.java - Emitted memory notification info. + Copyright (C) 2006 Free Software Foundation + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package java.lang.management; + +import gnu.java.lang.management.MemoryMXBeanImpl; + +import javax.management.openmbean.CompositeData; +import javax.management.openmbean.CompositeType; +import javax.management.openmbean.SimpleType; + +/** + * <p> + * Represents the content of a notification emitted by the + * {@link MemoryMXBean}. Such notifications are emitted when + * one of the memory pools exceeds its usage or collection + * usage threshold. This object contains the following information, + * representing the state of the pool at the time of the + * notification: + * </p> + * <ul> + * <li>The name of the pool.</li> + * <li>The memory usage of the pool at the time of notification.</li> + * <li>The number of times the pool has exceeded this particular + * threshold in the past.</li> + * </ul> + * <p> + * Two types of notification are emitted by the {@link MemoryMXBean}: + * one for exceeding the usage threshold and one for exceeding the + * collection usage threshold. The value returned by {@link #getCount()} + * is dependent on this type; if the threshold exceeded is the usage + * threshold, then the usage threshold count is returned. If, instead, + * the collection usage threshold is exceeded, then the collection usage + * threshold count is returned. + * </p> + * <p> + * This data is held in the user data part of the notification (returned + * by {@link javax.management.Notification#getUserData()}) encapsulated in + * a {@link javax.management.openmbean.CompositeData} object. The + * {@link #from(javax.management.openmbean.CompositeData)} method may be + * used to unwrap the value and obtain an instance of this class. + * </p> + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public class MemoryNotificationInfo +{ + + /** + * The type of notification emitted when the usage threshold is exceeded. + * After a notification is emitted, the usage level must drop below the + * threshold again before another notification is emitted. The value is + * <code>java.management.memory.threshold.exceeded</code>. + */ + public static final String MEMORY_THRESHOLD_EXCEEDED = + "java.management.memory.threshold.exceeded"; + + /** + * The type of notification emitted when the collection usage threshold + * is exceeded, following a garbage collection cycle. The value is + * <code>java.management.memory.collection.threshold.exceeded</code>. + */ + public static final String MEMORY_COLLECTION_THRESHOLD_EXCEEDED = + "java.management.memory.collection.threshold.exceeded"; + + /** + * The name of the memory pool which exceeded the threshold. + */ + private String poolName; + + /** + * The usage level of the memory pool at the time of notification. + */ + private MemoryUsage usage; + + /** + * The number of times the threshold has been crossed. + */ + private long count; + + /** + * Constructs a new {@link MemoryNotificationInfo} object using the + * specified pool name, usage level and threshold crossing count. + * + * @param poolName the name of the pool which has exceeded a threshold. + * @param usage the usage level of the pool at the time of notification. + * @param count the number of times the threshold has been crossed. + */ + public MemoryNotificationInfo(String poolName, MemoryUsage usage, long count) + { + this.poolName = poolName; + this.usage = usage; + this.count = count; + } + + /** + * <p> + * Returns a {@link MemoryNotificationInfo} instance using the values + * given in the supplied + * {@link javax.management.openmbean.CompositeData} object. + * The composite data instance should contain the following + * attributes with the specified types: + * </p> + * <table> + * <th><td>Name</td><td>Type</td></th> + * <tr><td>poolName</td><td>java.lang.String</td></tr> + * <tr><td>usage</td><td>javax.management.openmbean.CompositeData + * </td></tr> + * <tr><td>count</td><td>java.lang.Long</td></tr> + * </table> + * <p> + * The usage level is further described as: + * </p> + * <table> + * <th><td>Name</td><td>Type</td></th> + * <tr><td>init</td><td>java.lang.Long</td></tr> + * <tr><td>used</td><td>java.lang.Long</td></tr> + * <tr><td>committed</td><td>java.lang.Long</td></tr> + * <tr><td>max</td><td>java.lang.Long</td></tr> + * </table> + * + * @param data the composite data structure to take values from. + * @return a new instance containing the values from the + * composite data structure, or <code>null</code> + * if the data structure was also <code>null</code>. + * @throws IllegalArgumentException if the composite data structure + * does not match the structure + * outlined above. + */ + public static MemoryNotificationInfo from(CompositeData data) + { + if (data == null) + return null; + CompositeType type = data.getCompositeType(); + ThreadInfo.checkAttribute(type, "poolName", SimpleType.STRING); + ThreadInfo.checkAttribute(type, "usage", MemoryMXBeanImpl.usageType); + ThreadInfo.checkAttribute(type, "count", SimpleType.LONG); + MemoryUsage usage = MemoryUsage.from((CompositeData) data.get("usage")); + return new MemoryNotificationInfo(((String) data.get("poolName")), + usage, + ((Long) data.get("count")).longValue()); + } + + /** + * Returns the number of times the memory pool has crossed the usage + * threshold, as of the time of notification. If this is the notification + * represented by the type {@link #MEMORY_THRESHOLD_EXCEEDED}, then the + * count is the usage threshold count. If this is the notification + * represented by the type {@link #MEMORY_COLLECTION_THRESHOLD_EXCEEDED}, + * then the count is the collection usage threshold count. + * + * @return the number of times the appropriate threshold has been crossed. + */ + public long getCount() + { + return count; + } + + /** + * Returns the name of the pool which has crossed a threshold. + * + * @return the name of the pool. + */ + public String getPoolName() + { + return poolName; + } + + /** + * Returns the usage levels at the time of notification. + * + * @return the usage levels. + */ + public MemoryUsage getUsage() + { + return usage; + } + +} + diff --git a/libjava/classpath/java/lang/management/MemoryPoolMXBean.java b/libjava/classpath/java/lang/management/MemoryPoolMXBean.java new file mode 100644 index 0000000..5b04c64 --- /dev/null +++ b/libjava/classpath/java/lang/management/MemoryPoolMXBean.java @@ -0,0 +1,318 @@ +/* MemoryPoolMXBean.java - Interface for a memory pool bean + Copyright (C) 2006 Free Software Foundation + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package java.lang.management; + +/** + * <p> + * Provides access to information about one of the memory + * resources or pools used by the virtual machine. Instances + * of this bean are obtained by calling + * {@link ManagementFactory#getMemoryPoolMXBeans()}. One + * bean is returned for each memory pool provided. + * </p> + * <p> + * The memory pool bean allows the usage of the pool to be + * monitored. The bean can provide statistics on the current + * and peak usage of the pool, and on the threshold levels the + * pool uses. + * </p> + * <p> + * {@link getUsage()} returns an approximation of the current + * usage of the pool. Calls to this method are expected to be + * generally quick to perform; if the call is expensive, the + * documentation of the bean should specify so. For memory + * pool beans that represent the memory used by garbage + * collectors, the usage level includes both referenced and + * unreferenced objects. + * </p> + * <p> + * {@link getPeakUsage()} and {@link resetPeakUsage()} enable + * the retrieval of the peak usage level and setting it to the + * current usage level, respectively. Initially, the peak usage + * level is relative to the start of the virtual machine. + * </p> + * <p> + * Memory pools may also include optional support for usage thresholds. + * The usage threshold is a particular level of memory usage. When this + * value is crossed (the current memory usage becomes equal to or greater + * than this threshold level), the usage threshold count is increased. + * This feature is designed for monitoring the trend in memory usage. + * Support for a collection usage threshold is also provided, for + * particular garbage collectors. This is used to monitor the amount + * of memory left uncollected after a garbage collection cycle. There + * is no need to make special garbage collection runs to support this; + * the level following collection just needs to be monitored. + * </p> + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public interface MemoryPoolMXBean +{ + + /** + * Returns memory usage statistics after a best-effort attempt + * has been made to remove unused objects from the pool. This + * method is designed for use by the pools of garbage collectors, + * in order to monitor the amount of memory used after collections. + * It will return <code>null</code> if such functionality is + * unsupported by the memory pool represented by this bean. + * + * @return the memory usage of the memory pool after the most + * recent garbage collection cycle, or <code>null</code> + * if this operation is not supported. + */ + MemoryUsage getCollectionUsage(); + + /** + * Returns the collection usage threshold level in bytes. This + * value is initially zero. + * + * @return the collection usage threshold in bytes. + * @throws UnsupportedOperationException if the collection usage + * threshold is not supported. + * @see #getCollectionUsageThresholdCount() + * @see #isCollectionUsageThresholdExceeded() + * @see #isCollectionUsageThresholdSupported() + * @see #setCollectionUsageThreshold(long) + */ + long getCollectionUsageThreshold(); + + /** + * Returns the number of times the usage level has matched or + * exceeded the collection usage threshold. + * + * @return the number of times the usage level has matched + * or exceeded the collection usage threshold. + * @throws UnsupportedOperationException if the collection usage + * threshold is not supported. + * @see #getCollectionUsageThreshold() + * @see #isCollectionUsageThresholdExceeded() + * @see #isCollectionUsageThresholdSupported() + * @see #setCollectionUsageThreshold(long) + */ + long getCollectionUsageThresholdCount(); + + /** + * Returns the names of the memory managers associated with this + * pool. Each pool has at least one memory manager. + * + * @return an array containing the name of each memory manager + * responsible for this pool. + */ + String[] getMemoryManagerNames(); + + /** + * Returns the name of the memory pool. + * + * @return the memory pool name. + */ + String getName(); + + /** + * Returns memory usage statistics for the peak memory usage + * of the pool. The peak is the maximum memory usage occurring + * since the virtual machine was started or since the peak + * was reset by {@link #resetPeakUsage()}. The return value + * may be <code>null</code> if this pool is no longer valid. + * + * @return the memory usage of the memory pool at its peak, + * or <code>null</code> if this pool is no longer valid. + */ + MemoryUsage getPeakUsage(); + + /** + * Returns the type of memory used by this pool. This can be + * either heap or non-heap memory. + * + * @return the type of this pool. + */ + String getType(); + + /** + * Returns memory usage statistics for the current memory usage + * of the pool. The return value may be <code>null</code> if + * this pool is no longer valid. Obtaining these values is + * expected to be a relatively quick operation; if this will + * instead be an expensive operation to perform, the documentation + * of the implementating bean should specify that this is the + * case. The values are intended to be an estimate for monitoring + * purposes. + * + * @return the memory usage of the memory pool at present, + * or <code>null</code> if this pool is no longer valid. + */ + MemoryUsage getUsage(); + + /** + * Returns the usage threshold level in bytes. This + * value is initially defined by the virtual machine. + * + * @return the usage threshold in bytes. + * @throws UnsupportedOperationException if the usage threshold + * is not supported. + * @see #getUsageThresholdCount() + * @see #isUsageThresholdExceeded() + * @see #isUsageThresholdSupported() + * @see #setUsageThreshold(long) + */ + long getUsageThreshold(); + + /** + * Returns the number of times the usage level has matched or + * exceeded the usage threshold. + * + * @return the number of times the usage level has matched + * or exceeded the usage threshold. + * @throws UnsupportedOperationException if the usage threshold + * is not supported. + * @see #getUsageThreshold() + * @see #isUsageThresholdExceeded() + * @see #isUsageThresholdSupported() + * @see #setUsageThreshold(long) + */ + long getUsageThresholdCount(); + + /** + * Returns true if the collection usage level is equal to + * or greater than the collection usage threshold. + * + * @return true if the collection usage threshold has been + * matched or exceeded. + * @throws UnsupportedOperationException if the collection usage + * threshold is not supported. + * @see #getCollectionUsageThreshold() + * @see #getCollectionUsageThresholdCount() + * @see #isCollectionUsageThresholdSupported() + * @see #setCollectionUsageThreshold(long) + */ + boolean isCollectionUsageThresholdExceeded(); + + /** + * Returns true if this memory pool supports a collection usage + * level threshold. + * + * @return true if a collection usage level threshold is supported. + * @see #getCollectionUsageThreshold() + * @see #getCollectionUsageThresholdCount() + * @see #isCollectionUsageThresholdExceeded() + * @see #setCollectionUsageThreshold(long) + */ + boolean isCollectionUsageThresholdSupported(); + + /** + * Returns true if the usage level is equal to + * or greater than the usage threshold. + * + * @return true if the usage threshold has been + * matched or exceeded. + * @throws UnsupportedOperationException if the usage threshold + * is not supported. + * @see #getUsageThreshold() + * @see #getUsageThresholdCount() + * @see #isUsageThresholdSupported() + * @see #setUsageThreshold(long) + */ + boolean isUsageThresholdExceeded(); + + /** + * Returns true if this memory pool supports a usage level threshold. + * + * @return true if a usage level threshold is supported. + * @see #getUsageThreshold() + * @see #getUsageThresholdCount() + * @see #isUsageThresholdExceeded() + * @see #setUsageThreshold(long) + */ + boolean isUsageThresholdSupported(); + + /** + * Returns true if this memory pool is still valid. A memory pool + * becomes invalid when it is removed by the virtual machine and + * no longer used. + * + * @return true if this memory pool is valid. + */ + boolean isValid(); + + /** + * Resets the peak memory usage level to the current memory usage + * level. + * + * @throws SecurityException if a security manager exists and + * denies ManagementPermission("control"). + */ + void resetPeakUsage(); + + /** + * Sets the collection threshold usage level to the given value. + * A value of zero disables the collection threshold. + * + * @param threshold the new threshold level. + * @throws IllegalArgumentException if the threshold hold level + * is negative. + * @throws UnsupportedOperationException if the collection usage + * threshold is not supported. + * @throws SecurityException if a security manager exists and + * denies ManagementPermission("control"). + * @see #getCollectionUsageThreshold() + * @see #getCollectionUsageThresholdCount() + * @see #isCollectionUsageThresholdExceeded() + * @see #isCollectionUsageThresholdSupported() + */ + void setCollectionUsageThreshold(long threshold); + + /** + * Sets the threshold usage level to the given value. A value of + * zero disables the threshold. + * + * @param threshold the new threshold level. + * @throws IllegalArgumentException if the threshold hold level + * is negative. + * @throws UnsupportedOperationException if the usage threshold + * is not supported. + * @throws SecurityException if a security manager exists and + * denies ManagementPermission("control"). + * @see #getUsageThreshold() + * @see #getUsageThresholdCount() + * @see #isUsageThresholdExceeded() + * @see #isUsageThresholdSupported() + */ + void setUsageThreshold(long threshold); + +} diff --git a/libjava/classpath/java/lang/management/MemoryUsage.java b/libjava/classpath/java/lang/management/MemoryUsage.java new file mode 100644 index 0000000..3c2a4cb --- /dev/null +++ b/libjava/classpath/java/lang/management/MemoryUsage.java @@ -0,0 +1,265 @@ +/* MemoryUsage.java - Information on the usage of a memory pool. + Copyright (C) 2006 Free Software Foundation + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package java.lang.management; + +import javax.management.openmbean.CompositeData; +import javax.management.openmbean.CompositeType; +import javax.management.openmbean.SimpleType; +/** + * <p> + * Retains information on the usage of a particular memory + * pool, or heap/non-heap memory as a whole. Memory usage + * is represented by four values (all in bytes): + * </p> + * <ul> + * <li><strong>Initial Level</strong>: This is the initial + * amount of memory allocated for the pool by the operating + * system. This value may be undefined.</li> + * <li><strong>Used Level</strong>: This is the amount of + * memory currently in use.</li> + * <li><strong>Committed Level</strong>: This is the current + * amount of memory allocated for the pool by the operating + * system. This value will always be equal to or greater than + * the current amount of memory in use. It may drop below + * the initial amount, if the virtual machine judges this to + * be practical.</li> + * <li><strong>Maximum Level</strong>: This is the maximum + * amount of memory that may be allocated for the pool by + * the operating system. Like the initial amount, it may + * be undefined. If it is defined, it will be greater than + * or equal to the used and committed amounts and may change + * over time. It is not guaranteed that the maximum amount + * of memory may actually be allocated to the pool. For + * example, a request for an amount of memory greater than + * the current committed level, but less than the maximum, + * may still fail due to resources at the operating system + * level not being sufficient to fulfill the demand.</li> + * </ul> + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + * @see MemoryMXBean + * @see MemoryPoolMXBean + */ +public class MemoryUsage +{ + + /** + * The initial amount of memory allocated. + */ + private long init; + + /** + * The amount of memory used. + */ + private long used; + + /** + * The amount of memory committed for use. + */ + private long committed; + + /** + * The maximum amount of memory available. + */ + private long maximum; + + /** + * Constructs a new {@link MemoryUsage} object with + * the specified allocation levels. + * + * @param init the initial amount of memory allocated, + * or -1 if this value is undefined. Must + * be >= -1. + * @param used the amount of memory used. Must be >= 0, + * and <= committed. + * @param committed the amount of memory committed for use + * at present. Must be >= 0 and <= + * maximum (if defined). + * @param maximum the maximum amount of memory that may be + * used, or -1 if this value is undefined. + * Must be >= -1. + * @throws IllegalArgumentException if the values break any + * of the limits specified + * above. + */ + public MemoryUsage(long init, long used, long committed, + long maximum) + { + if (init < -1) + throw new IllegalArgumentException("Initial value of " + + init + " is too small."); + if (used < 0) + throw new IllegalArgumentException("Used value of " + + used + " is too small."); + if (committed < 0) + throw new IllegalArgumentException("Committed value of " + + committed + " is too small."); + if (committed < used) + throw new IllegalArgumentException("Committed value of " + + committed + " is below " + + used + ", the amount used."); + if (maximum < -1) + throw new IllegalArgumentException("Maximum value of " + + maximum + " is too small."); + if (maximum != -1 && maximum < committed) + throw new IllegalArgumentException("Maximum value of " + + maximum + " is below " + + committed + ", the amount " + + "committed."); + this.init = init; + this.used = used; + this.committed = committed; + this.maximum = maximum; + } + + /** + * <p> + * Returns a {@link MemoryUsage} instance using the values + * given in the supplied + * {@link javax.management.openmbean.CompositeData} object. + * The composite data instance should contain the following + * attributes: + * </p> + * <ul> + * <li>init</li> + * <li>used</li> + * <li>committed</li> + * <li>max</li> + * </ul> + * <p> + * All should have the type, <code>java.lang.Long</code>. + * </p> + * + * @param data the composite data structure to take values from. + * @return a new instance containing the values from the + * composite data structure, or <code>null</code> + * if the data structure was also <code>null</code>. + * @throws IllegalArgumentException if the composite data structure + * does not match the structure + * outlined above, or the values + * are invalid. + */ + public static MemoryUsage from(CompositeData data) + { + if (data == null) + return null; + CompositeType type = data.getCompositeType(); + ThreadInfo.checkAttribute(type, "init", SimpleType.LONG); + ThreadInfo.checkAttribute(type, "used", SimpleType.LONG); + ThreadInfo.checkAttribute(type, "committed", SimpleType.LONG); + ThreadInfo.checkAttribute(type, "max", SimpleType.LONG); + return new MemoryUsage(((Long) data.get("init")).longValue(), + ((Long) data.get("used")).longValue(), + ((Long) data.get("committed")).longValue(), + ((Long) data.get("max")).longValue()); + } + + /** + * Returns the amount of memory committed for use by this + * memory pool (in bytes). This amount is guaranteed to + * be available, unlike the maximum. + * + * @return the committed amount of memory. + */ + public long getCommitted() + { + return committed; + } + + /** + * Returns the initial amount of memory allocated to the + * pool (in bytes). This method may return -1, if the + * value is undefined. + * + * @return the initial amount of memory allocated, or -1 + * if this value is undefined. + */ + public long getInit() + { + return init; + } + + /** + * Returns the maximum amount of memory available for this + * pool (in bytes). This amount is not guaranteed to + * actually be usable. This method may return -1, if the + * value is undefined. + * + * @return the maximum amount of memory available, or -1 + * if this value is undefined. + */ + public long getMax() + { + return maximum; + } + + /** + * Returns the amount of memory used (in bytes). + * + * @return the amount of used memory. + */ + public long getUsed() + { + return used; + } + + /** + * Returns a {@link java.lang.String} representation of + * this {@link MemoryUsage} object. This takes the form + * <code>java.lang.management.MemoryUsage[init=i, used=u, + * committed=c, maximum=m]</code>, where <code>i</code> + * is the initial level, <code>u</code> is the used level, + * <code>c</code> is the committed level and <code>m</code> + * is the maximum level. + * + * @return the string specified above. + */ + public String toString() + { + int megabyte = 1024 * 1024; + return getClass().getName() + + "[init=" + init + " bytes (~" + (init / megabyte) + + "MB), used=" + used + " bytes (~" + (used / megabyte) + + "MB), committed=" + committed + " bytes (~" + (committed / megabyte) + + "MB), maximum=" + maximum + " bytes (~" + (maximum / megabyte) + + "MB)]"; + } + +} + diff --git a/libjava/classpath/java/lang/management/OperatingSystemMXBean.java b/libjava/classpath/java/lang/management/OperatingSystemMXBean.java new file mode 100644 index 0000000..2430a9f --- /dev/null +++ b/libjava/classpath/java/lang/management/OperatingSystemMXBean.java @@ -0,0 +1,103 @@ +/* OperatingSystemMXBean.java - Interface for an operating system bean + Copyright (C) 2006 Free Software Foundation + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package java.lang.management; + +/** + * Provides access to information about the underlying operating + * system. An instance of this bean is obtained by calling + * {@link ManagementFactory#getOperatingSystemMXBean()}. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public interface OperatingSystemMXBean +{ + + /** + * Returns the name of the underlying system architecture. This + * is equivalent to obtaining the <code>os.arch</code> property + * via {@link System#getProperty(String)}. + * + * @return the name of the underlying system architecture on which + * the VM is running. + * @throws SecurityException if a security manager exists which + * prevents access to the name property. + * @see java.lang.System#getProperty(String) + * @see java.lang.SecurityManager#checkPropertyAccess(String) + */ + String getArch(); + + /** + * Returns the number of processors currently available to the + * virtual machine. This number is subject to change during + * execution of the virtual machine, and will always be >= 1. + * The call is equivalent to {@link Runtime#availableProcessors()}. + * + * @return the number of processors available to the VM. + */ + int getAvailableProcessors(); + + /** + * Returns the name of the underlying operating system. This + * is equivalent to obtaining the <code>os.name</code> property + * via {@link System#getProperty(String)}. + * + * @return the name of the operating system on which the VM + * is running. + * @throws SecurityException if a security manager exists which + * prevents access to the name property. + * @see java.lang.System#getProperty(String) + * @see java.lang.SecurityManager#checkPropertyAccess(String) + */ + String getName(); + + /** + * Returns the version of the underlying operating system. This + * is equivalent to obtaining the <code>os.version</code> property + * via {@link System#getProperty(String)}. + * + * @return the version of the operating system on which the VM + * is running. + * @throws SecurityException if a security manager exists which + * prevents access to the name property. + * @see java.lang.System#getProperty(String) + * @see java.lang.SecurityManager#checkPropertyAccess(String) + */ + String getVersion(); + +} diff --git a/libjava/classpath/java/lang/management/RuntimeMXBean.java b/libjava/classpath/java/lang/management/RuntimeMXBean.java new file mode 100644 index 0000000..cee1d80 --- /dev/null +++ b/libjava/classpath/java/lang/management/RuntimeMXBean.java @@ -0,0 +1,278 @@ +/* RuntimeMXBean.java - Interface for a runtime bean + Copyright (C) 2006 Free Software Foundation + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package java.lang.management; + +import java.util.List; +import java.util.Map; + +/** + * Provides access to information about the underlying virtual + * machine. An instance of this bean is obtained by calling + * {@link ManagementFactory#getRuntimeMXBean()}. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public interface RuntimeMXBean +{ + + /** + * <p> + * Returns the boot classpath used by the virtual machine. This + * value follows the standard path syntax used by the underlying + * operating system (e.g. directories separated by ':' on UNIX + * or ';' on Windows). + * </p> + * <p> + * Supplying this value is optional. Users should check the + * return value of {@link isBootClassPathSupported()} prior to + * calling this method. + * </p> + * + * @return the boot classpath of the virtual machine, if supported. + * @throws UnsupportedOperationException in cases where this + * functionality is not + * supported by the VM. + * @throws SecurityException if a security manager exists and + * denies ManagementPermission("monitor"). + * @see #isBootClassPathSupported() + * @see java.lang.management.ManagementPermission + */ + String getBootClassPath(); + + /** + * Returns the classpath used by the system classloader. This + * is equivalent to obtaining the <code>java.class.path</code> + * property via {@link System#getProperty(String)}. This value + * follows the standard path syntax used by the underlying operating + * system (e.g. directories separated by ':' on UNIX or ';' on + * Windows). + * + * @return the classpath used by the system class loader. + * @throws SecurityException if a security manager exists which + * prevents access to the classpath + * property. + * @see java.lang.System#getProperty(String) + * @see java.lang.SecurityManager#checkPropertyAccess(String) + */ + String getClassPath(); + + /** + * Returns a list of the arguments given to the virtual machine, + * excluding those that apply to the <code>main()</code> method + * of the class file being executed. These may not just be those + * specified at the command line, but may also include arguments + * from environment variables, configuration files, etc. All + * command line arguments may not reach the virtual machine, so + * these are not included in this list. + * + * @return a list of arguments passed to the virtual machine. + * @throws SecurityException if a security manager exists and + * denies ManagementPermission("monitor"). + * @see java.lang.management.ManagementPermission + */ + List getInputArguments(); + + /** + * Returns the library path. This is equivalent to obtaining the + * <code>java.library.path</code> property via + * {@link System#getProperty(String)}. This value follows the + * standard path syntax used by the underlying operating + * system (e.g. directories separated by ':' on UNIX or ';' on + * Windows). + * + * @return the library path. + * @throws SecurityException if a security manager exists which + * prevents access to the library path + * property. + * @see java.lang.System#getProperty(String) + * @see java.lang.SecurityManager#checkPropertyAccess(String) + */ + String getLibraryPath(); + + /** + * Returns the version of the management specification + * implemented by the virtual machine. + * + * @return the version of the management specification + * implemented. + */ + String getManagementSpecVersion(); + + /** + * Returns the name of this virtual machine. The content + * of this property is left up to the developer of the + * virtual machine. It may include a number of system + * attributes and may differ between instances of the + * same virtual machine (for example, it might include + * the process identifier or the host name of the machine + * on which it is running). The intention is that this + * name refers to the precise entity that the other data + * supplied by this bean refers to, rather than the VM + * in general. + * + * @return the name of this virtual machine. + */ + String getName(); + + /** + * Returns the specification name of the virtual machine. + * This is equivalent to obtaining the + * <code>java.vm.specification.name</code> property via + * {@link System#getProperty(String)}. + * + * @return the specification name of the VM. + * @throws SecurityException if a security manager exists which + * prevents access to the VM + * specification name property. + * @see java.lang.System#getProperty(String) + * @see java.lang.SecurityManager#checkPropertyAccess(String) + */ + String getSpecName(); + + /** + * Returns the specification vendor of the virtual machine. + * This is equivalent to obtaining the + * <code>java.vm.specification.vendor</code> property via + * {@link System#getProperty(String)}. + * + * @return the specification vendor of the VM. + * @throws SecurityException if a security manager exists which + * prevents access to the VM + * specification vendor property. + * @see java.lang.System#getProperty(String) + * @see java.lang.SecurityManager#checkPropertyAccess(String) + */ + String getSpecVendor(); + + /** + * Returns the specification version of the virtual machine. + * This is equivalent to obtaining the + * <code>java.vm.specification.version</code> property via + * {@link System#getProperty(String)}. + * + * @return the specification version of the VM. + * @throws SecurityException if a security manager exists which + * prevents access to the VM + * specification version property. + * @see java.lang.System#getProperty(String) + * @see java.lang.SecurityManager#checkPropertyAccess(String) + */ + String getSpecVersion(); + + /** + * Returns the approximate start time of the virtual machine + * in milliseconds. + * + * @return the start time of the virtual machine. + */ + long getStartTime(); + + /** + * Returns a map containing the keys and values of the system + * properties. This gives largely the same result as calling + * {@link System#getProperties()}, but the resulting map + * is filtered so as to only provide keys and values that + * are <code>String</code>s. + * + * @return the map of system properties. + */ + Map getSystemProperties(); + + /** + * Returns the uptime of the virtual machine in milliseconds. + * + * @return the uptime of the virtual machine. + */ + long getUptime(); + + /** + * Returns the implementation name of the virtual machine. + * This is equivalent to obtaining the + * <code>java.vm.name</code> property via + * {@link System#getProperty(String)}. + * + * @return the implementation name of the VM. + * @throws SecurityException if a security manager exists which + * prevents access to the VM name + * property. + * @see java.lang.System#getProperty(String) + * @see java.lang.SecurityManager#checkPropertyAccess(String) + */ + String getVmName(); + + /** + * Returns the implementation vendor of the virtual machine. + * This is equivalent to obtaining the + * <code>java.vm.vendor</code> property via + * {@link System#getProperty(String)}. + * + * @return the implementation vendor of the VM. + * @throws SecurityException if a security manager exists which + * prevents access to the VM vendor + * property. + * @see java.lang.System#getProperty(String) + * @see java.lang.SecurityManager#checkPropertyAccess(String) + */ + String getVmVendor(); + + /** + * Returns the implementation version of the virtual machine. + * This is equivalent to obtaining the + * <code>java.vm.version</code> property via + * {@link System#getProperty(String)}. + * + * @return the implementation version of the VM. + * @throws SecurityException if a security manager exists which + * prevents access to the VM version + * property. + * @see java.lang.System#getProperty(String) + * @see java.lang.SecurityManager#checkPropertyAccess(String) + */ + String getVmVersion(); + + /** + * Returns true if the virtual machine supports the boot classpath + * mechanism. + * + * @return true if the boot classpath property is supported by the + * virtual machine. + */ + boolean isBootClassPathSupported(); + +} diff --git a/libjava/classpath/java/lang/management/ThreadInfo.java b/libjava/classpath/java/lang/management/ThreadInfo.java new file mode 100644 index 0000000..4bf35a4 --- /dev/null +++ b/libjava/classpath/java/lang/management/ThreadInfo.java @@ -0,0 +1,704 @@ +/* ThreadInfo.java - Information on a thread + Copyright (C) 2006 Free Software Foundation + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package java.lang.management; + +import javax.management.openmbean.ArrayType; +import javax.management.openmbean.CompositeData; +import javax.management.openmbean.CompositeType; +import javax.management.openmbean.OpenDataException; +import javax.management.openmbean.OpenType; +import javax.management.openmbean.SimpleType; + +/** + * <p> + * A class which maintains information about a particular + * thread. This information includes: + * </p> + * <ul> + * <li><strong>General Thread Information:</strong> + * <ul> + * <li>The identifier of the thread.</li> + * <li>The name of the thread.</li> + * </ul> + * </li> + * <li><strong>Execution Information:</strong> + * <ul> + * <li>The current state of the thread (e.g. blocked, runnable)</li> + * <li>The object upon which the thread is blocked, either because + * the thread is waiting to obtain the monitor of that object to enter + * one of its synchronized monitor, or because + * {@link java.lang.Object#wait()} has been called while the thread + * was within a method of that object.</li> + * <li>The thread identifier of the current thread holding an object's + * monitor, upon which the thread described here is blocked.</li> + * <li>The stack trace of the thread (if requested on creation + * of this object</li> + * </ul> + * <li><strong>Synchronization Statistics</strong> + * <ul> + * <li>The number of times the thread has been blocked waiting for + * an object's monitor or in a {@link java.lang.Object#wait()} call.</li> + * <li>The accumulated time the thread has been blocked waiting for + * an object's monitor on in a {@link java.lang.Object#wait()} call. + * The availability of these statistics depends on the virtual machine's + * support for thread contention monitoring (see + * {@link ThreadMXBean#isThreadContentionMonitoringSupported()}.</li> + * </ul> + * </li> + * </ul> + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + * @see ThreadMXBean#isThreadContentionMonitoringSupported() + */ +public class ThreadInfo +{ + + /** + * The id of the thread which this instance concerns. + */ + private long threadId; + + /** + * The name of the thread which this instance concerns. + */ + private String threadName; + + /** + * The state of the thread which this instance concerns. + */ + private String threadState; + + /** + * The number of times the thread has been blocked. + */ + private long blockedCount; + + /** + * The accumulated number of milliseconds the thread has + * been blocked (used only with thread contention monitoring + * support). + */ + private long blockedTime; + + /** + * The name of the monitor lock on which this thread + * is blocked (if any). + */ + private String lockName; + + /** + * The id of the thread which owns the monitor lock on + * which this thread is blocked, or <code>-1</code> + * if there is no owner. + */ + private long lockOwnerId; + + /** + * The name of the thread which owns the monitor lock on + * which this thread is blocked, or <code>null</code> + * if there is no owner. + */ + private String lockOwnerName; + + /** + * The number of times the thread has been in a waiting + * state. + */ + private long waitedCount; + + /** + * The accumulated number of milliseconds the thread has + * been waiting (used only with thread contention monitoring + * support). + */ + private long waitedTime; + + /** + * True if the thread is in a native method. + */ + private boolean isInNative; + + /** + * True if the thread is suspended. + */ + private boolean isSuspended; + + /** + * The stack trace of the thread. + */ + private StackTraceElement[] trace; + + /** + * Cache a local reference to the thread management bean. + */ + private static ThreadMXBean bean = null; + + /** + * Constructs a new {@link ThreadInfo} corresponding + * to the thread specified. + * + * @param thread the thread on which the new instance + * will be based. + * @param blockedCount the number of times the thread + * has been blocked. + * @param blockedTime the accumulated number of milliseconds + * the specified thread has been blocked + * (only used with contention monitoring enabled) + * @param lock the monitor lock the thread is waiting for + * (only used if blocked) + * @param lockOwner the thread which owns the monitor lock, or + * <code>null</code> if it doesn't have an owner + * (only used if blocked) + * @param waitedCount the number of times the thread has been in a + * waiting state. + * @param waitedTime the accumulated number of milliseconds the + * specified thread has been waiting + * (only used with contention monitoring enabled) + * @param isInNative true if the thread is in a native method. + * @param isSuspended true if the thread is suspended. + * @param trace the stack trace of the thread to a pre-determined + * depth (see VMThreadMXBeanImpl) + */ + private ThreadInfo(Thread thread, long blockedCount, long blockedTime, + Object lock, Thread lockOwner, long waitedCount, + long waitedTime, boolean isInNative, boolean isSuspended, + StackTraceElement[] trace) + { + this(thread.getId(), thread.getName(), thread.getState(), blockedCount, + blockedTime, lock.getClass().getName() + "@" + + Integer.toHexString(System.identityHashCode(lock)), lockOwner.getId(), + lockOwner.getName(), waitedCount, waitedTime, isInNative, isSuspended, + trace); + } + + /** + * Constructs a new {@link ThreadInfo} corresponding + * to the thread details specified. + * + * @param threadId the id of the thread on which this + * new instance will be based. + * @param threadName the name of the thread on which + * this new instance will be based. + * @param threadState the state of the thread on which + * this new instance will be based. + * @param blockedCount the number of times the thread + * has been blocked. + * @param blockedTime the accumulated number of milliseconds + * the specified thread has been blocked + * (only used with contention monitoring enabled) + * @param lockName the name of the monitor lock the thread is waiting for + * (only used if blocked) + * @param lockOwnerId the id of the thread which owns the monitor + * lock, or <code>-1</code> if it doesn't have an owner + * (only used if blocked) + * @param lockOwnerName the name of the thread which owns the monitor + * lock, or <code>null</code> if it doesn't have an + * owner (only used if blocked) + * @param waitedCount the number of times the thread has been in a + * waiting state. + * @param waitedTime the accumulated number of milliseconds the + * specified thread has been waiting + * (only used with contention monitoring enabled) + * @param isInNative true if the thread is in a native method. + * @param isSuspended true if the thread is suspended. + * @param trace the stack trace of the thread to a pre-determined + * depth (see VMThreadMXBeanImpl) + */ + private ThreadInfo(long threadId, String threadName, String threadState, + long blockedCount, long blockedTime, String lockName, + long lockOwnerId, String lockOwnerName, long waitedCount, + long waitedTime, boolean isInNative, boolean isSuspended, + StackTraceElement[] trace) + { + this.threadId = threadId; + this.threadName = threadName; + this.threadState = threadState; + this.blockedCount = blockedCount; + this.blockedTime = blockedTime; + this.lockName = lockName; + this.lockOwnerId = lockOwnerId; + this.lockOwnerName = lockOwnerName; + this.waitedCount = waitedCount; + this.waitedTime = waitedTime; + this.isInNative = isInNative; + this.isSuspended = isSuspended; + this.trace = trace; + } + + /** + * Checks for an attribute in a {@link CompositeData} structure + * with the correct type. + * + * @param ctype the composite data type to check. + * @param name the name of the attribute. + * @param type the type to check for. + * @throws IllegalArgumentException if the attribute is absent + * or of the wrong type. + */ + static void checkAttribute(CompositeType ctype, String name, + OpenType type) + throws IllegalArgumentException + { + OpenType foundType = ctype.getType(name); + if (foundType == null) + throw new IllegalArgumentException("Could not find a field named " + + name); + if (!(foundType.equals(type))) + throw new IllegalArgumentException("Field " + name + " is not of " + + "type " + type.getClassName()); + } + + /** + * <p> + * Returns a {@link ThreadInfo} instance using the values + * given in the supplied + * {@link javax.management.openmbean.CompositeData} object. + * The composite data instance should contain the following + * attributes with the specified types: + * </p> + * <table> + * <th><td>Name</td><td>Type</td></th> + * <tr><td>threadId</td><td>java.lang.Long</td></tr> + * <tr><td>threadName</td><td>java.lang.String</td></tr> + * <tr><td>threadState</td><td>java.lang.String</td></tr> + * <tr><td>suspended</td><td>java.lang.Boolean</td></tr> + * <tr><td>inNative</td><td>java.lang.Boolean</td></tr> + * <tr><td>blockedCount</td><td>java.lang.Long</td></tr> + * <tr><td>blockedTime</td><td>java.lang.Long</td></tr> + * <tr><td>waitedCount</td><td>java.lang.Long</td></tr> + * <tr><td>waitedTime</td><td>java.lang.Long</td></tr> + * <tr><td>lockName</td><td>java.lang.String</td></tr> + * <tr><td>lockOwnerId</td><td>java.lang.Long</td></tr> + * <tr><td>lockOwnerName</td><td>java.lang.String</td></tr> + * <tr><td>stackTrace</td><td>javax.management.openmbean.CompositeData[] + * </td></tr> + * </table> + * <p> + * The stack trace is further described as: + * </p> + * <table> + * <th><td>Name</td><td>Type</td></th> + * <tr><td>className</td><td>java.lang.String</td></tr> + * <tr><td>methodName</td><td>java.lang.String</td></tr> + * <tr><td>fileName</td><td>java.lang.String</td></tr> + * <tr><td>lineNumber</td><td>java.lang.Integer</td></tr> + * <tr><td>nativeMethod</td><td>java.lang.Boolean</td></tr> + * </table> + * + * @param data the composite data structure to take values from. + * @return a new instance containing the values from the + * composite data structure, or <code>null</code> + * if the data structure was also <code>null</code>. + * @throws IllegalArgumentException if the composite data structure + * does not match the structure + * outlined above. + */ + public static ThreadInfo from(CompositeData data) + { + if (data == null) + return null; + CompositeType type = data.getCompositeType(); + checkAttribute(type, "threadId", SimpleType.LONG); + checkAttribute(type, "threadName", SimpleType.STRING); + checkAttribute(type, "threadState", SimpleType.STRING); + checkAttribute(type, "suspended", SimpleType.BOOLEAN); + checkAttribute(type, "inNative", SimpleType.BOOLEAN); + checkAttribute(type, "blockedCount", SimpleType.LONG); + checkAttribute(type, "blockedTime", SimpleType.LONG); + checkAttribute(type, "waitedCount", SimpleType.LONG); + checkAttribute(type, "waitedTime", SimpleType.LONG); + checkAttribute(type, "lockName", SimpleType.STRING); + checkAttribute(type, "lockOwnerId", SimpleType.LONG); + checkAttribute(type, "lockOwnerName", SimpleType.STRING); + try + { + CompositeType seType = + new CompositeType(StackTraceElement.class.getName(), + "An element of a stack trace", + new String[] { "className", "methodName", + "fileName", "lineNumber", + "nativeMethod" + }, + new String[] { "Name of the class", + "Name of the method", + "Name of the source code file", + "Line number", + "True if this is a native method" + }, + new OpenType[] { + SimpleType.STRING, SimpleType.STRING, + SimpleType.STRING, SimpleType.INTEGER, + SimpleType.BOOLEAN + }); + checkAttribute(type, "stackTrace", new ArrayType(1, seType)); + } + catch (OpenDataException e) + { + throw new IllegalStateException("Something went wrong in creating " + + "the composite data type for the " + + "stack trace element.", e); + } + CompositeData[] dTraces = (CompositeData[]) data.get("stackTrace"); + StackTraceElement[] traces = new StackTraceElement[dTraces.length]; + for (int a = 0; a < dTraces.length; ++a) + /* FIXME: We can't use the boolean as there is no available + constructor. */ + traces[a] = + new StackTraceElement((String) dTraces[a].get("className"), + (String) dTraces[a].get("methodName"), + (String) dTraces[a].get("fileName"), + ((Integer) + dTraces[a].get("lineNumber")).intValue()); + return new ThreadInfo(((Long) data.get("threadId")).longValue(), + (String) data.get("threadName"), + (String) data.get("threadState"), + ((Long) data.get("blockedCount")).longValue(), + ((Long) data.get("blockedTime")).longValue(), + (String) data.get("lockName"), + ((Long) data.get("lockOwnerId")).longValue(), + (String) data.get("lockOwnerName"), + ((Long) data.get("waitedCount")).longValue(), + ((Long) data.get("waitedTime")).longValue(), + ((Boolean) data.get("inNative")).booleanValue(), + ((Boolean) data.get("suspended")).booleanValue(), + traces); + } + + /** + * Returns the number of times this thread has been + * in the {@link java.lang.Thread.State#BLOCKED} state. + * A thread enters this state when it is waiting to + * obtain an object's monitor. This may occur either + * on entering a synchronized method for the first time, + * or on re-entering it following a call to + * {@link java.lang.Object#wait()}. + * + * @return the number of times this thread has been blocked. + */ + public long getBlockedCount() + { + return blockedCount; + } + + /** + * <p> + * Returns the accumulated number of milliseconds this + * thread has been in the + * {@link java.lang.Thread.State#BLOCKED} state + * since thread contention monitoring was last enabled. + * A thread enters this state when it is waiting to + * obtain an object's monitor. This may occur either + * on entering a synchronized method for the first time, + * or on re-entering it following a call to + * {@link java.lang.Object#wait()}. + * </p> + * <p> + * Use of this method requires virtual machine support + * for thread contention monitoring and for this support + * to be enabled. + * </p> + * + * @return the accumulated time (in milliseconds) that this + * thread has spent in the blocked state, since + * thread contention monitoring was enabled, or -1 + * if thread contention monitoring is disabled. + * @throws UnsupportedOperationException if the virtual + * machine does not + * support contention + * monitoring. + * @see ThreadMXBean#isThreadContentionMonitoringEnabled() + * @see ThreadMXBean#isThreadContentionMonitoringSupported() + */ + public long getBlockedTime() + { + if (bean == null) + bean = ManagementFactory.getThreadMXBean(); + // Will throw UnsupportedOperationException for us + if (bean.isThreadContentionMonitoringEnabled()) + return blockedTime; + else + return -1; + } + + /** + * <p> + * Returns a {@link java.lang.String} representation of + * the monitor lock on which this thread is blocked. If + * the thread is not blocked, this method returns + * <code>null</code>. + * </p> + * <p> + * The returned {@link java.lang.String} is constructed + * using the class name and identity hashcode (usually + * the memory address of the object) of the lock. The + * two are separated by the '@' character, and the identity + * hashcode is represented in hexadecimal. Thus, for a + * lock, <code>l</code>, the returned value is + * the result of concatenating + * <code>l.getClass().getName()</code>, <code>"@"</code> + * and + * <code>Integer.toHexString(System.identityHashCode(l))</code>. + * The value is only unique to the extent that the identity + * hash code is also unique. + * </p> + * + * @return a string representing the lock on which this + * thread is blocked, or <code>null</code> if + * the thread is not blocked. + */ + public String getLockName() + { + if (threadState.equals("BLOCKED")) + return null; + return lockName; + } + + /** + * Returns the identifier of the thread which owns the + * monitor lock this thread is waiting for. -1 is returned + * if either this thread is not blocked, or the lock is + * not held by any other thread. + * + * @return the thread identifier of thread holding the lock + * this thread is waiting for, or -1 if the thread + * is not blocked or the lock is not held by another + * thread. + */ + public long getLockOwnerId() + { + if (threadState.equals("BLOCKED")) + return -1; + return lockOwnerId; + } + + /** + * Returns the name of the thread which owns the + * monitor lock this thread is waiting for. <code>null</code> + * is returned if either this thread is not blocked, + * or the lock is not held by any other thread. + * + * @return the thread identifier of thread holding the lock + * this thread is waiting for, or <code>null</code> + * if the thread is not blocked or the lock is not + * held by another thread. + */ + public String getLockOwnerName() + { + if (threadState.equals("BLOCKED")) + return null; + return lockOwnerName; + } + + /** + * <p> + * Returns the stack trace of this thread to the depth + * specified on creation of this {@link ThreadInfo} + * object. If the depth is zero, an empty array will + * be returned. For non-zero arrays, the elements + * start with the most recent trace at position zero. + * The bottom of the stack represents the oldest method + * invocation which meets the depth requirements. + * </p> + * <p> + * Some virtual machines may not be able to return + * stack trace information for a thread. In these + * cases, an empty array will also be returned. + * </p> + * + * @return an array of {@link java.lang.StackTraceElement}s + * representing the trace of this thread. + */ + public StackTraceElement[] getStackTrace() + { + return trace; + } + + /** + * Returns the identifier of the thread associated with + * this instance of {@link ThreadInfo}. + * + * @return the thread's identifier. + */ + public long getThreadId() + { + return threadId; + } + + /** + * Returns the name of the thread associated with + * this instance of {@link ThreadInfo}. + * + * @return the thread's name. + */ + public String getThreadName() + { + return threadName; + } + + /** + * Returns the state of the thread associated with + * this instance of {@link ThreadInfo}. + * + * @return the thread's state. + */ + public String getThreadState() + { + return threadState; + } + + /** + * Returns the number of times this thread has been + * in the {@link java.lang.Thread.State#WAITING} + * or {@link java.lang.Thread.State#TIMED_WAITING} state. + * A thread enters one of these states when it is waiting + * due to a call to {@link java.lang.Object.wait()}, + * {@link java.lang.Object.join()} or + * {@link java.lang.concurrent.locks.LockSupport.park()}, + * either with an infinite or timed delay, respectively. + * + * @return the number of times this thread has been waiting. + */ + public long getWaitedCount() + { + return waitedCount; + } + + /** + * <p> + * Returns the accumulated number of milliseconds this + * thread has been in the + * {@link java.lang.Thread.State#WAITING} or + * {@link java.lang.Thread.State#TIMED_WAITING} state, + * since thread contention monitoring was last enabled. + * A thread enters one of these states when it is waiting + * due to a call to {@link java.lang.Object.wait()}, + * {@link java.lang.Object.join()} or + * {@link java.lang.concurrent.locks.LockSupport.park()}, + * either with an infinite or timed delay, respectively. + * </p> + * <p> + * Use of this method requires virtual machine support + * for thread contention monitoring and for this support + * to be enabled. + * </p> + * + * @return the accumulated time (in milliseconds) that this + * thread has spent in one of the waiting states, since + * thread contention monitoring was enabled, or -1 + * if thread contention monitoring is disabled. + * @throws UnsupportedOperationException if the virtual + * machine does not + * support contention + * monitoring. + * @see ThreadMXBean#isThreadContentionMonitoringEnabled() + * @see ThreadMXBean#isThreadContentionMonitoringSupported() + */ + public long getWaitedTime() + { + if (bean == null) + bean = ManagementFactory.getThreadMXBean(); + // Will throw UnsupportedOperationException for us + if (bean.isThreadContentionMonitoringEnabled()) + return waitedTime; + else + return -1; + } + + /** + * Returns true if the thread is in a native method. This + * excludes native code which forms part of the virtual + * machine itself, or which results from Just-In-Time + * compilation. + * + * @return true if the thread is in a native method, false + * otherwise. + */ + public boolean isInNative() + { + return isInNative; + } + + /** + * Returns true if the thread has been suspended using + * {@link java.lang.Thread#suspend()}. + * + * @return true if the thread is suspended, false otherwise. + */ + public boolean isSuspended() + { + return isSuspended; + } + + /** + * Returns a {@link java.lang.String} representation of + * this {@link ThreadInfo} object. This takes the form + * <code>java.lang.management.ThreadInfo[id=tid, name=n, + * state=s, blockedCount=bc, waitedCount=wc, isInNative=iin, + * isSuspended=is]</code>, where <code>tid</code> is + * the thread identifier, <code>n</code> is the + * thread name, <code>s</code> is the thread state, + * <code>bc</code> is the blocked state count, + * <code>wc</code> is the waiting state count and + * <code>iin</code> and <code>is</code> are boolean + * flags to indicate the thread is in native code or + * suspended respectively. If the thread is blocked, + * <code>lock=l, lockOwner=lo</code> is also included, + * where <code>l</code> is the lock waited for, and + * <code>lo</code> is the thread which owns the lock + * (or null if there is no owner). + * + * @return the string specified above. + */ + public String toString() + { + return getClass().getName() + + "[id=" + threadId + + ", name=" + threadName + + ", state=" + threadState + + ", blockedCount=" + blockedCount + + ", waitedCount=" + waitedCount + + ", isInNative=" + isInNative + + ", isSuspended=" + isSuspended + + (threadState.equals("BLOCKED") ? + ", lockOwnerId=" + lockOwnerId + + ", lockOwnerName=" + lockOwnerName : "") + + "]"; + } + +} diff --git a/libjava/classpath/java/lang/management/ThreadMXBean.java b/libjava/classpath/java/lang/management/ThreadMXBean.java new file mode 100644 index 0000000..669cb3c --- /dev/null +++ b/libjava/classpath/java/lang/management/ThreadMXBean.java @@ -0,0 +1,497 @@ +/* ThreadMXBean.java - Interface for a thread bean + Copyright (C) 2006 Free Software Foundation + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package java.lang.management; + +/** + * <p> + * Provides access to information about the threads + * of the virtual machine. An instance of this bean is + * obtained by calling + * {@link ManagementFactory#getThreadMXBean()}. + * </p> + * <p> + * Each thread within the virtual machine is given an + * identifier, which is guaranteed to be unique to a + * particular thread over its lifetime (after which it + * may be reused). The identifier for a thread may be + * obtained by calling {@link java.lang.Thread#getId()}. + * This identifier is used within implementations of this + * interface to obtain information about a particular thread + * (or series of threads, in the case of an array of identifiers). + * </p> + * <p> + * This bean supports some optional behaviour, which all + * virtual machines may not choose to implement. Specifically, + * this includes the monitoring of the CPU time used by a + * thread, and the monitoring of thread contention. The former + * is further subdivided into the monitoring of either just + * the current thread or all threads. The methods + * {@link #isThreadCpuTimeSupported()}, + * {@link #isCurrentThreadCpuTimeSupported()} and + * {@link #isThreadContentionMonitoringSupported()} may be + * used to determine whether or not this functionality is + * supported. + * </p> + * <p> + * Furthermore, both these facilities may be disabled. + * In fact, thread contention monitoring is disabled by + * default, and must be explictly turned on by calling + * the {@link #setThreadContentionMonitoringEnabled(boolean)} + * method. + * </p> + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public interface ThreadMXBean +{ + + /** + * <p> + * This method obtains a list of threads which are deadlocked + * waiting to obtain monitor ownership. On entering a synchronized + * method of an object, or re-entering it after returning from an + * {@link java.lang.Object#wait()} call, a thread obtains ownership + * of the object's monitor. + * </p> + * <p> + * Deadlocks can occur in this situation if one or more threads end up + * waiting for a monitor, P, while also retaining ownership of a monitor, + * Q, required by the thread that currently owns P. To give a simple + * example, imagine thread A calls a synchronized method, R, obtaining the + * monitor, P. It then sleeps within that method, allowing thread B + * to run, but still retaining ownership of P. B calls another + * synchronized method, S, which causes it to obtain the monitor, Q, + * of a different object. While in that method, it then wants to + * call the original synchronized method, R, called by A. Doing so + * requires ownership of P, which is still held by A. Hence, it + * becomes blocked. + * </p> + * <p> + * A then finishes its sleep, becomes runnable, and is then allowed + * to run, being the only eligible thread in this scenario. A tries + * to call the synchronized method, S. It also gets blocked, because + * B still holds the monitor, Q. Hence, the two threads, A and B, + * are deadlocked, as neither can give up its monitor without first + * obtaining the monitor held by the other thread. + * </p> + * <p> + * Calling this method in this scenario would return the thread IDs + * of A and B. Note that this method is not designed for controlling + * synchronization, but for troubleshooting problems which cause such + * deadlocks; it may be prohibitively expensive to use in normal + * operation. + * </p> + * + * @return an array of thread identifiers, corresponding to threads + * which are currently in a deadlocked situation. + * @throws SecurityException if a security manager exists and + * denies ManagementPermission("monitor"). + */ + long[] findMonitorDeadlockedThreads(); + + /** + * Returns all live thread identifiers at the time of initial + * execution. Some thread identifiers in the returned array + * may refer to terminated threads, if this occurs during the + * lifetime of this method. + * + * @return an array of thread identifiers, corresponding to + * current live threads. + * @throws SecurityException if a security manager exists and + * denies ManagementPermission("monitor"). + */ + long[] getAllThreadIds(); + + /** + * <p> + * Returns the total number of nanoseconds of CPU time + * the current thread has used. This is equivalent to calling + * <code>{@link #getThreadCpuTime()}(Thread.currentThread.getId())</code>. + * </p> + * <p> + * Note that the value is only nanosecond-precise, and not accurate; there + * is no guarantee that the difference between two values is really a + * nanosecond. Also, the value is prone to overflow if the offset + * exceeds 2^63. The use of this method depends on virtual machine + * support for measurement of the CPU time of the current thread, + * and on this functionality being enabled. + * </p> + * + * @return the total number of nanoseconds of CPU time the current + * thread has used, or -1 if CPU time monitoring is disabled. + * @throws UnsupportedOperationException if CPU time monitoring is not + * supported. + * @see #getCurrentThreadUserTime() + * @see #isCurrentThreadCpuTimeSupported() + * @see #isThreadCpuTimeEnabled() + * @see #setThreadCpuTimeEnabled(boolean) + */ + long getCurrentThreadCpuTime(); + + /** + * <p> + * Returns the total number of nanoseconds of CPU time + * the current thread has executed in user mode. This is + * equivalent to calling + * <code>{@link #getThreadUserTime()}(Thread.currentThread.getId())</code>. + * </p> + * <p> + * Note that the value is only nanosecond-precise, and not accurate; there + * is no guarantee that the difference between two values is really a + * nanosecond. Also, the value is prone to overflow if the offset + * exceeds 2^63. The use of this method depends on virtual machine + * support for measurement of the CPU time of the current thread, + * and on this functionality being enabled. + * </p> + * + * @return the total number of nanoseconds of CPU time the current + * thread has executed in user mode, or -1 if CPU time + * monitoring is disabled. + * @throws UnsupportedOperationException if CPU time monitoring is not + * supported. + * @see #getCurrentThreadCpuTime() + * @see #isCurrentThreadCpuTimeSupported() + * @see #isThreadCpuTimeEnabled() + * @see #setThreadCpuTimeEnabled(boolean) + */ + long getCurrentThreadUserTime(); + + /** + * Returns the number of live daemon threads. + * + * @return the number of live daemon threads. + */ + int getDaemonThreadCount(); + + /** + * Returns the peak number of live threads since + * the virtual machine was started or the count + * reset using {@link #resetPeakThreadCount()}. + * + * @return the peak live thread count. + * @see #resetPeakThreadCount() + */ + int getPeakThreadCount(); + + /** + * Returns the number of live threads, including + * both daemon threads and non-daemon threads. + * + * @return the current number of live threads. + */ + int getThreadCount(); + + /** + * <p> + * Returns the total number of nanoseconds of CPU time + * the specified thread has used. + * </p> + * <p> + * Note that the value is only nanosecond-precise, and not accurate; there + * is no guarantee that the difference between two values is really a + * nanosecond. Also, the value is prone to overflow if the offset + * exceeds 2^63. The use of this method depends on virtual machine + * support for measurement of the CPU time of the current thread, + * and on this functionality being enabled. + * </p> + * + * @param id the thread identifier of the thread whose CPU time is being + * monitored. + * @return the total number of nanoseconds of CPU time the specified + * thread has used, or -1 if CPU time monitoring is disabled. + * @throws IllegalArgumentException if <code>id</code> <= 0. + * @throws UnsupportedOperationException if CPU time monitoring is not + * supported. + * @see #getThreadUserTime(long) + * @see #isThreadCpuTimeSupported() + * @see #isThreadCpuTimeEnabled() + * @see #setThreadCpuTimeEnabled(boolean) + */ + long getThreadCpuTime(long id); + + /** + * Returns information on the specified thread without any + * stack trace information. This is equivalent to + * <code>{@link #getThreadInfo}(id, 0)</code>. If the + * identifier specifies a thread which is either non-existant + * or not alive, then the method returns <code>null</code>. + * + * @param id the identifier of the thread to return information + * on. + * @return a {@link ThreadInfo} object pertaining to the specified + * thread, or <code>null</code> if the identifier specifies + * a thread that doesn't exist or is not alive. + * @throws IllegalArgumentException if <code>id</code> <= 0. + * @throws SecurityException if a security manager exists and + * denies ManagementPermission("monitor"). + */ + ThreadInfo getThreadInfo(long id); + + /** + * Returns information on the specified threads without any + * stack trace information. This is equivalent to + * <code>{@link #getThreadInfo}(ids, 0)</code>. If an + * identifier specifies a thread which is either non-existant + * or not alive, then the corresponding element in the returned + * array is <code>null</code>. + * + * @param ids an array of thread identifiers to return information + * on. + * @return an array of {@link ThreadInfo} objects matching the + * specified threads. The corresponding element is + * <code>null</code> if the identifier specifies + * a thread that doesn't exist or is not alive. + * @throws IllegalArgumentException if an identifier in the array is + * <= 0. + * @throws SecurityException if a security manager exists and + * denies ManagementPermission("monitor"). + */ + ThreadInfo[] getThreadInfo(long[] ids); + + /** + * Returns information on the specified thread with + * stack trace information to the supplied depth. If the + * identifier specifies a thread which is either non-existant + * or not alive, then the method returns <code>null</code>. + * A maximum depth of 0 corresponds to an empty stack trace + * (an empty array is returned by the appropriate + * {@link ThreadInfo} method). A maximum depth of + * <code>Integer.MAX_VALUE</code> returns the full stack trace. + * + * @param id the identifier of the thread to return information + * on. + * @param maxDepth the maximum depth of the stack trace. + * Values of 0 or <code>Integer.MAX_VALUE</code> + * correspond to an empty and full stack trace + * respectively. + * @return a {@link ThreadInfo} object pertaining to the specified + * thread, or <code>null</code> if the identifier specifies + * a thread that doesn't exist or is not alive. + * @throws IllegalArgumentException if <code>id</code> <= 0. + * @throws IllegalArgumentException if <code>maxDepth</code> < 0. + * @throws SecurityException if a security manager exists and + * denies ManagementPermission("monitor"). + */ + ThreadInfo getThreadInfo(long id, int maxDepth); + + /** + * Returns information on the specified threads with + * stack trace information to the supplied depth. If an + * identifier specifies a thread which is either non-existant + * or not alive, then the corresponding element in the returned + * array is <code>null</code>. A maximum depth of 0 corresponds + * to an empty stack trace (an empty array is returned by the + * appropriate {@link ThreadInfo} method). A maximum depth of + * <code>Integer.MAX_VALUE</code> returns the full stack trace. + * + * @param ids an array of thread identifiers to return information + * on. + * @param maxDepth the maximum depth of the stack trace. + * Values of 0 or <code>Integer.MAX_VALUE</code> + * correspond to an empty and full stack trace + * respectively. + * @return an array of {@link ThreadInfo} objects matching the + * specified threads. The corresponding element is + * <code>null</code> if the identifier specifies + * a thread that doesn't exist or is not alive. + * @throws IllegalArgumentException if an identifier in the array is + * <= 0. + * @throws IllegalArgumentException if <code>maxDepth</code> < 0. + * @throws SecurityException if a security manager exists and + * denies ManagementPermission("monitor"). + */ + ThreadInfo[] getThreadInfo(long[] ids, int maxDepth); + + /** + * <p> + * Returns the total number of nanoseconds of CPU time + * the specified thread has executed in user mode. + * </p> + * <p> + * Note that the value is only nanosecond-precise, and not accurate; there + * is no guarantee that the difference between two values is really a + * nanosecond. Also, the value is prone to overflow if the offset + * exceeds 2^63. The use of this method depends on virtual machine + * support for measurement of the CPU time of the current thread, + * and on this functionality being enabled. + * </p> + * + * @param id the thread identifier of the thread whose CPU time is being + * monitored. + * @return the total number of nanoseconds of CPU time the specified + * thread has executed in user mode, or -1 if CPU time monitoring + * is disabled. + * @throws IllegalArgumentException if <code>id</code> <= 0. + * @throws UnsupportedOperationException if CPU time monitoring is not + * supported. + * @see #getThreadCpuTime(long) + * @see #isThreadCpuTimeSupported() + * @see #isThreadCpuTimeEnabled() + * @see #setThreadCpuTimeEnabled(boolean) + */ + long getThreadUserTime(long id); + + /** + * Returns the total number of threads that have been + * created and started during the lifetime of the virtual + * machine. + * + * @return the total number of started threads. + */ + long getTotalStartedThreadCount(); + + /** + * Returns true if the virtual machine supports the monitoring + * of the CPU time used by the current thread. This is implied + * by {@link isThreadCpuTimeSupported()} returning true. + * + * @return true if monitoring of the CPU time used by the current + * thread is supported by the virtual machine. + * @see #isThreadCpuTimeEnabled() + * @see #isThreadCpuTimeSupported() + * @see #setThreadCpuTimeEnabled(boolean) + */ + boolean isCurrentThreadCpuTimeSupported(); + + /** + * Returns true if thread contention monitoring is currently + * enabled. + * + * @return true if thread contention monitoring is enabled. + * @throws UnsupportedOperationException if the virtual + * machine does not + * support contention + * monitoring. + * @see #isThreadContentionMonitoringSupported() + * @see #setThreadContentionMonitoringEnabled(boolean) + */ + boolean isThreadContentionMonitoringEnabled(); + + /** + * Returns true if thread contention monitoring is supported + * by the virtual machine. + * + * @return true if thread contention monitoring is supported + * by the virtual machine. + * @see #isThreadContentionMonitoringEnabled() + * @see #setThreadContentionMonitoringEnabled(boolean) + */ + boolean isThreadContentionMonitoringSupported(); + + /** + * Returns true if monitoring of the CPU time used by a thread + * is currently enabled. + * + * @return true if thread CPU time monitoring is enabled. + * @throws UnsupportedOperationException if the virtual + * machine does not + * support CPU time + * monitoring. + * @see #isCurrentThreadCpuTimeSupported() + * @see #isThreadCpuTimeSupported() + * @see #setThreadCpuTimeEnabled(boolean) + */ + boolean isThreadCpuTimeEnabled(); + + /** + * Returns true if the virtual machine supports the monitoring + * of the CPU time used by all threads. This implies + * that {@link isCurrentThreadCpuTimeSupported()} returns true. + * + * @return true if monitoring of the CPU time used by the current + * thread is supported by the virtual machine. + * @see #isCurrentThreadCpuTimeSupported() + * @see #isThreadCpuTimeEnabled() + * @see #setThreadCpuTimeEnabled(boolean) + */ + boolean isThreadCpuTimeSupported(); + + /** + * Resets the peak live thread count to the + * current number of live threads, as returned + * by {@link #getThreadCount()}. + * + * @see #getPeakThreadCount() + * @see #getThreadCount() + * @throws SecurityException if a security manager exists and + * denies ManagementPermission("control"). + */ + void resetPeakThreadCount(); + + /** + * Toggles the monitoring of thread contention. Thread + * contention monitoring is disabled by default. Each + * time contention monitoring is re-enabled, the times + * it maintains are reset. + * + * @param enable true if monitoring should be enabled, + * false if it should be disabled. + * @throws UnsupportedOperationException if the virtual + * machine does not + * support contention + * monitoring. + * @throws SecurityException if a security manager exists and + * denies ManagementPermission("control"). + * @see #isThreadContentionMonitoringEnabled() + * @see #isThreadContentionMonitoringSupported() + */ + void setThreadContentionMonitoringEnabled(boolean enable); + + /** + * Toggles the monitoring of CPU time used by threads. The + * initial setting is dependent on the underlying virtual + * machine. On enabling CPU time monitoring, the virtual + * machine may take any value up to and including the current + * time as the start time for monitoring. + * + * @param enable true if monitoring should be enabled, + * false if it should be disabled. + * @throws UnsupportedOperationException if the virtual + * machine does not + * support CPU time + * monitoring. + * @throws SecurityException if a security manager exists and + * denies ManagementPermission("control"). + * @see #isCurrentThreadCpuTimeSupported() + * @see #isThreadCpuTimeEnabled() + * @see #isThreadCpuTimeSupported() + */ + void setThreadCpuTimeEnabled(boolean enable); + +} diff --git a/libjava/classpath/java/lang/management/package.html b/libjava/classpath/java/lang/management/package.html new file mode 100644 index 0000000..1b37cc1 --- /dev/null +++ b/libjava/classpath/java/lang/management/package.html @@ -0,0 +1,64 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> +<!-- package.html - describes classes in java.lang.management package. + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. --> + +<html> +<head><title>GNU Classpath - java.lang.management</title></head> + +<body> + +<p> +A series of management beans which provide access to information about the +virtual machine and its underlying operating system. +</p> +<p>The following beans are provided:</p> +<ul> +<li> +<span style="font-weight: bold;">{@link java.lang.management.OperatingSystemMXBean} </span> +— Information about the underlying operating system. +</li> +</ul> +<h2>Accessing the Beans</h2> +<p> +An instance of a bean can be obtained by using one of the following methods: +</p> +<ol> +<li>Calling the appropriate static method of the {@link java.lang.management.ManagementFactory} +</li> +</ol> +</body> +</html> |