diff options
Diffstat (limited to 'libjava/classpath/java/lang/management')
18 files changed, 4600 insertions, 0 deletions
diff --git a/libjava/classpath/java/lang/management/ClassLoadingMXBean.java b/libjava/classpath/java/lang/management/ClassLoadingMXBean.java new file mode 100644 index 000000000..491af247f --- /dev/null +++ b/libjava/classpath/java/lang/management/ClassLoadingMXBean.java @@ -0,0 +1,102 @@ +/* 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 000000000..36f69c44b --- /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 000000000..f3da0042d --- /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/LockInfo.java b/libjava/classpath/java/lang/management/LockInfo.java new file mode 100644 index 000000000..ae5166834 --- /dev/null +++ b/libjava/classpath/java/lang/management/LockInfo.java @@ -0,0 +1,114 @@ +/* LockInfo.java - Information on a lock. + 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.beans.ConstructorProperties; + +/** + * Provides information on a lock held by a thread. + * A lock can be either a built-in monitor, an + * <emph>ownable synchronizer</emph> (i.e. a subclass + * of {@link java.util.concurrent.locks.AbstractOwnableSynchronizer}), + * or a {@link java.util.concurrent.locks.Condition} + * object. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.6 + */ +public class LockInfo +{ + + /** + * The class name of the lock object. + */ + private String className; + + /** + * The identity hash code of the lock object. + */ + private int identityHashCode; + + /** + * Constructs a new {@link LockInfo} object with the + * specified class name and identity hash code. + * + * @param className the name of the class of the lock object. + * @param identityHashCode the identity hash code of the + * lock object. + */ + @ConstructorProperties({"className","identityHashCode"}) + public LockInfo(String className, int identityHashCode) + { + this.className = className; + this.identityHashCode = identityHashCode; + } + + /** + * Returns the class name of the lock object. + * + * @return the class name of the lock object. + */ + public String getClassName() + { + return className; + } + + /** + * Returns the identity hash code of the lock object. + * + * @return the identity hash code of the lock object. + */ + public int getIdentityHashCode() + { + return identityHashCode; + } + + /** + * Returns a textual representation of the lock, + * constructed by concatenating the class name, + * <code>'@'</code> and the identity hash code + * in unsigned hexadecimal form. + * + * @return a textual representation of the lock. + */ + public String toString() + { + return className + '@' + Integer.toHexString(identityHashCode); + } + +} diff --git a/libjava/classpath/java/lang/management/ManagementFactory.java b/libjava/classpath/java/lang/management/ManagementFactory.java new file mode 100644 index 000000000..c054f5dd9 --- /dev/null +++ b/libjava/classpath/java/lang/management/ManagementFactory.java @@ -0,0 +1,817 @@ +/* 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.io.IOException; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import java.util.logging.LogManager; + +import javax.management.Attribute; +import javax.management.InstanceAlreadyExistsException; +import javax.management.MBeanRegistrationException; +import javax.management.MBeanServer; +import javax.management.MBeanServerConnection; +import javax.management.MBeanServerFactory; +import javax.management.MalformedObjectNameException; +import javax.management.NotCompliantMBeanException; +import javax.management.NotificationEmitter; +import javax.management.NotificationFilter; +import javax.management.NotificationListener; +import javax.management.ObjectName; + +import javax.management.openmbean.CompositeData; +import javax.management.openmbean.TabularData; + +/** + * <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> + * <li>Using the platform {@link javax.management.MBeanServer} + * to access the beans locally, or an + * {@link javax.management.MBeanServerConnection} for remote + * access. The attributes and operations use the limited + * range of data types specified below.</li> + * </ol> + * <h2>Open Data Types</h2> + * <p> + * The data types used by the management beans are restricted + * to <emph>open</emph> data types to aid interoperability. This + * allows the beans to be accessed remotely, including from non-Java + * clients. Below is a table which lists the types used by the beans + * on the left, and the types they are converted to when returned via + * a bean server on the right. Type information is provided for each + * bean by obtaining its instance of {@link javax.management.MBeanInfo}. + * </p> + * <table> + * <th><td>Data Type Used</td><td>Data Type Returned</td></th> + * <tr> + * <td>Primitive types (<code>int</code>, <code>char</code>, etc.)</td> + * <td>Same</td> + * </tr><tr> + * <td>Wrapper classes ({@link{java.lang.Integer}, + * @link{java.lang.Character}, etc.)</td> + * <td>Same</td> + * </tr><tr> + * <td>An {@link java.lang.Enum}</td> + * <td>The <code>name</code> of the enumeration constant</td> + * </tr><tr> + * <td>An array of type <code>E</code></td> + * <td>An array of the same dimensions with this mapping applied + * to <code>E</code>.</td> + * </tr><tr> + * <td>A class with `getter' methods and a + * <code>from({@link javax.management.openmbean.CompositeData})</code> + * method.</td> + * <td>The equivalent {@link javax.management.openmbean.CompositeData} + * instance, specified by the <code>from</code> method.</td> + * </tr><tr> + * <td>A map with keys of type <code>K</code> and values of + * type <code>V</code>.</td> + * <td>A {@link javax.management.openmbean.TabularData} instance, + * with the row type containing two items, <code>"key"</code> and + * <code>"value"</code> with the types <code>K</code> and <code>V</code> + * respectively (with translation applied).</td> + * </tr><tr> + * <td>A list of type <code>E</code>.</td> + * <td>An array with this mapping applied to <code>E</code>.</td> + * </tr></table> + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public class ManagementFactory +{ + + /** + * The object name for the class loading bean. + */ + public static final String CLASS_LOADING_MXBEAN_NAME = + "java.lang:type=ClassLoading"; + + /** + * The object name for the compilation bean. + */ + public static final String COMPILATION_MXBEAN_NAME = + "java.lang:type=Compilation"; + + /** + * The domain for the garbage collecting beans. + */ + public static final String GARBAGE_COLLECTOR_MXBEAN_DOMAIN_TYPE = + "java.lang:type=GarbageCollector"; + + /** + * The domain for the memory manager beans. + */ + public static final String MEMORY_MANAGER_MXBEAN_DOMAIN_TYPE = + "java.lang:type=MemoryManager"; + + /** + * The object name for the memory bean. + */ + public static final String MEMORY_MXBEAN_NAME = + "java.lang:type=Memory"; + + /** + * The domain for the memory pool beans. + */ + public static final String MEMORY_POOL_MXBEAN_DOMAIN_TYPE = + "java.lang:type=MemoryPool"; + + /** + * The object name for the operating system bean. + */ + public static final String OPERATING_SYSTEM_MXBEAN_NAME = + "java.lang:type=OperatingSystem"; + + /** + * The object name for the runtime bean. + */ + public static final String RUNTIME_MXBEAN_NAME = + "java.lang:type=Runtime"; + + /** + * The object name for the threading bean. + */ + public static final String THREAD_MXBEAN_NAME = + "java.lang:type=Threading"; + + /** + * 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; + + /** + * The platform server. + */ + private static MBeanServer platformServer; + + /** + * 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<MemoryPoolMXBean> getMemoryPoolMXBeans() + { + List<MemoryPoolMXBean> poolBeans = + new ArrayList<MemoryPoolMXBean>(); + 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<MemoryManagerMXBean> getMemoryManagerMXBeans() + { + List<MemoryManagerMXBean> managerBeans = + new ArrayList<MemoryManagerMXBean>(); + 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<GarbageCollectorMXBean> getGarbageCollectorMXBeans() + { + List<GarbageCollectorMXBean> gcBeans = + new ArrayList<GarbageCollectorMXBean>(); + 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; + } + + /** + * <p> + * Returns the platform {@link javax.management.MBeanServer}. On the + * first call to this method, a server instance is retrieved from + * the {@link javax.management.MBeanServerFactory} and each of the + * beans are registered with it. Subsequent calls return the existing + * instance. If the property <code>javax.management.builder.initial</code> + * is set, its value will be used as the name of the class which is used + * to provide the server instance. + * </p> + * <p> + * It is recommended that the platform server is used for other beans as + * well, in order to simplify their discovery and publication. Name conflicts + * should be avoided. + * </p> + * + * @return the platform {@link javax.management.MBeanServer} + * @throws SecurityException if a security manager exists and the + * caller's permissions don't imply {@link + * MBeanServerPermission(String)}("createMBeanServer") + * @see javax.management.MBeanServerFactory + * @see javax.management.MBeanServerFactory#createMBeanServer() + */ + public static MBeanServer getPlatformMBeanServer() + { + if (platformServer == null) + { + platformServer = MBeanServerFactory.createMBeanServer(); + try + { + platformServer.registerMBean(getOperatingSystemMXBean(), + new ObjectName(OPERATING_SYSTEM_MXBEAN_NAME)); + platformServer.registerMBean(getRuntimeMXBean(), + new ObjectName(RUNTIME_MXBEAN_NAME)); + platformServer.registerMBean(getClassLoadingMXBean(), + new ObjectName(CLASS_LOADING_MXBEAN_NAME)); + platformServer.registerMBean(getThreadMXBean(), + new ObjectName(THREAD_MXBEAN_NAME)); + platformServer.registerMBean(getMemoryMXBean(), + new ObjectName(MEMORY_MXBEAN_NAME)); + CompilationMXBean compBean = getCompilationMXBean(); + if (compBean != null) + platformServer.registerMBean(compBean, + new ObjectName(COMPILATION_MXBEAN_NAME)); + Iterator beans = getMemoryPoolMXBeans().iterator(); + while (beans.hasNext()) + { + MemoryPoolMXBean bean = (MemoryPoolMXBean) beans.next(); + platformServer.registerMBean(bean, + new ObjectName(MEMORY_POOL_MXBEAN_DOMAIN_TYPE + + ",name=" + + bean.getName())); + } + beans = getMemoryManagerMXBeans().iterator(); + while (beans.hasNext()) + { + MemoryManagerMXBean bean = (MemoryManagerMXBean) beans.next(); + platformServer.registerMBean(bean, + new ObjectName(MEMORY_MANAGER_MXBEAN_DOMAIN_TYPE + + ",name=" + + bean.getName())); + } + beans = getGarbageCollectorMXBeans().iterator(); + while (beans.hasNext()) + { + GarbageCollectorMXBean bean = (GarbageCollectorMXBean) beans.next(); + platformServer.registerMBean(bean, + new ObjectName(GARBAGE_COLLECTOR_MXBEAN_DOMAIN_TYPE + + ",name=" + + bean.getName())); + } + platformServer.registerMBean(LogManager.getLoggingMXBean(), + new ObjectName(LogManager.LOGGING_MXBEAN_NAME)); + } + catch (InstanceAlreadyExistsException e) + { + throw (Error) + (new InternalError("One of the management beans is " + + "already registered.").initCause(e)); + } + catch (MBeanRegistrationException e) + { + throw (Error) + (new InternalError("One of the management beans' preRegister " + + "methods threw an exception.").initCause(e)); + } + catch (NotCompliantMBeanException e) + { + throw (Error) + (new InternalError("One of the management beans is " + + "not compliant.").initCause(e)); + } + catch (MalformedObjectNameException e) + { + throw (Error) + (new InternalError("The object name of a management bean is " + + "not compliant.").initCause(e)); + } + } + return platformServer; + } + + /** + * <p> + * Returns a proxy for the specified platform bean. A proxy object is created + * using <code>Proxy.newProxyInstance(mxbeanInterface.getClassLoader(), + * new Class[] { mxbeanInterface }, handler)</code>. The + * {@link javax.management.NotificationEmitter} class is also added to the + * array if the bean provides notifications. <code>handler</code> refers + * to the invocation handler which forwards calls to the connection, and + * also provides translation between the Java data types used in the + * bean interfaces and the open data types, as specified in the description + * of this class. It is this translation that makes the + * usual {@link javax.management.MBeanServerInvocationHandler} inappropriate + * for providing such a proxy. + * </p> + * <p> + * <strong>Note</strong>: use of the proxy may result in + * {@link java.io.IOException}s from the underlying {@link MBeanServerConnection} + * and a {@link java.io.InvalidObjectException} if enum constants + * used on the client and the server don't match. + * </p> + * + * @param connection the server connection to use to access the bean. + * @param mxbeanName the {@link javax.management.ObjectName} of the + * bean to provide a proxy for. + * @param mxbeanInterface the interface for the bean being proxied. + * @return a proxy for the specified bean. + * @throws IllegalArgumentException if <code>mxbeanName</code> is not a valid + * {@link javax.management.ObjectName}, + * the interface and name do not match the + * same bean, the name does not refer to a + * platform bean or the bean is not registered + * with the server accessed by <code>connection</code>. + * @throws IOException if the connection throws one. + */ + public static <T> T newPlatformMXBeanProxy(MBeanServerConnection connection, + String mxbeanName, + Class<T> mxbeanInterface) + throws IOException + { + if (!(mxbeanName.equals(CLASS_LOADING_MXBEAN_NAME) || + mxbeanName.equals(COMPILATION_MXBEAN_NAME) || + mxbeanName.startsWith(GARBAGE_COLLECTOR_MXBEAN_DOMAIN_TYPE) || + mxbeanName.startsWith(MEMORY_MANAGER_MXBEAN_DOMAIN_TYPE) || + mxbeanName.equals(MEMORY_MXBEAN_NAME) || + mxbeanName.startsWith(MEMORY_POOL_MXBEAN_DOMAIN_TYPE) || + mxbeanName.equals(OPERATING_SYSTEM_MXBEAN_NAME) || + mxbeanName.equals(RUNTIME_MXBEAN_NAME) || + mxbeanName.equals(THREAD_MXBEAN_NAME))) + { + throw new IllegalArgumentException("The named bean, " + mxbeanName + + ", is not a platform name."); + } + if ((mxbeanName.equals(CLASS_LOADING_MXBEAN_NAME) && + mxbeanInterface != ClassLoadingMXBean.class) || + (mxbeanName.equals(COMPILATION_MXBEAN_NAME) && + mxbeanInterface != CompilationMXBean.class) || + (mxbeanName.startsWith(GARBAGE_COLLECTOR_MXBEAN_DOMAIN_TYPE) && + mxbeanInterface != GarbageCollectorMXBean.class) || + (mxbeanName.startsWith(MEMORY_MANAGER_MXBEAN_DOMAIN_TYPE) && + mxbeanInterface != MemoryManagerMXBean.class) || + (mxbeanName.equals(MEMORY_MXBEAN_NAME) && + mxbeanInterface != MemoryMXBean.class) || + (mxbeanName.startsWith(MEMORY_POOL_MXBEAN_DOMAIN_TYPE) && + mxbeanInterface != MemoryPoolMXBean.class) || + (mxbeanName.equals(OPERATING_SYSTEM_MXBEAN_NAME) && + mxbeanInterface != OperatingSystemMXBean.class) || + (mxbeanName.equals(RUNTIME_MXBEAN_NAME) && + mxbeanInterface != RuntimeMXBean.class) || + (mxbeanName.equals(THREAD_MXBEAN_NAME) && + mxbeanInterface != ThreadMXBean.class)) + throw new IllegalArgumentException("The interface, " + mxbeanInterface + + ", does not match the bean, " + mxbeanName); + ObjectName bean; + try + { + bean = new ObjectName(mxbeanName); + } + catch (MalformedObjectNameException e) + { + throw new IllegalArgumentException("The named bean is invalid."); + } + if (!(connection.isRegistered(bean))) + throw new IllegalArgumentException("The bean is not registered on this connection."); + Class[] interfaces; + if (mxbeanName.equals(MEMORY_MXBEAN_NAME)) + interfaces = new Class[] { mxbeanInterface, NotificationEmitter.class }; + else + interfaces = new Class[] { mxbeanInterface }; + return (T) Proxy.newProxyInstance(mxbeanInterface.getClassLoader(), + interfaces, + new ManagementInvocationHandler(connection, bean)); + } + + /** + * This invocation handler provides method calls for a platform bean + * by forwarding them to a {@link MBeanServerConnection}. Translation from + * Java data types to open data types is performed as specified above. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ + private static class ManagementInvocationHandler + implements InvocationHandler + { + + /** + * The encapsulated connection. + */ + private MBeanServerConnection conn; + + /** + * The bean being proxied. + */ + private ObjectName bean; + + /** + * Constructs a new {@link InvocationHandler} which proxies + * for the specified bean using the supplied connection. + * + * @param conn the connection on which to forward method calls. + * @param bean the bean to proxy. + */ + public ManagementInvocationHandler(MBeanServerConnection conn, + ObjectName bean) + throws IOException + { + this.conn = conn; + this.bean = bean; + } + + /** + * Called by the proxy class whenever a method is called. The method + * is emulated by retrieving an attribute from, setting an attribute on + * or invoking a method on the server connection as required. Translation + * between the Java data types supplied as arguments to the open types used + * by the bean is provided, as well as translation of the return value back + * in to the appropriate Java type. + * + * @param proxy the proxy on which the method was called. + * @param method the method which was called. + * @param args the arguments supplied to the method. + * @return the return value from the method. + * @throws Throwable if an exception is thrown in performing the + * method emulation. + */ + public Object invoke(Object proxy, Method method, Object[] args) + throws Throwable + { + String name = method.getName(); + if (name.equals("toString")) + return "Proxy for " + bean + " using " + conn; + if (name.equals("addNotificationListener")) + { + conn.addNotificationListener(bean, + (NotificationListener) args[0], + (NotificationFilter) args[1], + args[2]); + return null; + } + if (name.equals("getNotificationInfo")) + return conn.getMBeanInfo(bean).getNotifications(); + if (name.equals("removeNotificationListener")) + { + if (args.length == 1) + conn.removeNotificationListener(bean, + (NotificationListener) + args[0]); + else + conn.removeNotificationListener(bean, + (NotificationListener) + args[0], + (NotificationFilter) + args[1], args[2]); + return null; + } + String attrib = null; + if (name.startsWith("get")) + attrib = name.substring(3); + else if (name.startsWith("is")) + attrib = name.substring(2); + if (attrib != null) + return translate(conn.getAttribute(bean, attrib), method); + else if (name.startsWith("set")) + { + conn.setAttribute(bean, new Attribute(name.substring(3), + args[0])); + return null; + } + else + return translate(conn.invoke(bean, name, args, null), method); + } + + /** + * Translates the returned open data type to the value + * required by the interface. + * + * @param otype the open type returned by the method call. + * @param method the method that was called. + * @return the equivalent return type required by the interface. + * @throws Throwable if an exception is thrown in performing the + * conversion. + */ + private final Object translate(Object otype, Method method) + throws Throwable + { + Class<?> returnType = method.getReturnType(); + if (returnType.isEnum()) + { + String ename = (String) otype; + Enum[] constants = (Enum[]) returnType.getEnumConstants(); + for (Enum c : constants) + if (c.name().equals(ename)) + return c; + } + if (List.class.isAssignableFrom(returnType)) + { + Object[] elems = (Object[]) otype; + List l = new ArrayList(elems.length); + for (Object elem : elems) + l.add(elem); + return l; + } + if (Map.class.isAssignableFrom(returnType)) + { + TabularData data = (TabularData) otype; + Map m = new HashMap(data.size()); + for (Object val : data.values()) + { + CompositeData vals = (CompositeData) val; + m.put(vals.get("key"), vals.get("value")); + } + return m; + } + try + { + Method m = returnType.getMethod("from", + new Class[] + { CompositeData.class }); + return m.invoke(null, (CompositeData) otype); + } + catch (NoSuchMethodException e) + { + /* Ignored; we expect this if this + isn't a from(CompositeData) class */ + } + return otype; + } + + } +} diff --git a/libjava/classpath/java/lang/management/ManagementPermission.java b/libjava/classpath/java/lang/management/ManagementPermission.java new file mode 100644 index 000000000..73794571c --- /dev/null +++ b/libjava/classpath/java/lang/management/ManagementPermission.java @@ -0,0 +1,131 @@ +/* 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 000000000..acf0e6795 --- /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 000000000..1b10e998f --- /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 000000000..85856e058 --- /dev/null +++ b/libjava/classpath/java/lang/management/MemoryNotificationInfo.java @@ -0,0 +1,214 @@ +/* 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 000000000..9729093b2 --- /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. + */ + MemoryType 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/MemoryType.java b/libjava/classpath/java/lang/management/MemoryType.java new file mode 100644 index 000000000..c864d5407 --- /dev/null +++ b/libjava/classpath/java/lang/management/MemoryType.java @@ -0,0 +1,50 @@ +/* MemoryType.java - Enumeration of the types of memory pools. + 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; + +/** + * Enumerates the possible types of memory pools. A value of this + * type is returned by {@link MemoryPoolMXBean#getMemoryType()}. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public enum MemoryType +{ + HEAP, NON_HEAP; +} diff --git a/libjava/classpath/java/lang/management/MemoryUsage.java b/libjava/classpath/java/lang/management/MemoryUsage.java new file mode 100644 index 000000000..42aef3cc5 --- /dev/null +++ b/libjava/classpath/java/lang/management/MemoryUsage.java @@ -0,0 +1,264 @@ +/* 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/MonitorInfo.java b/libjava/classpath/java/lang/management/MonitorInfo.java new file mode 100644 index 000000000..fd7233716 --- /dev/null +++ b/libjava/classpath/java/lang/management/MonitorInfo.java @@ -0,0 +1,179 @@ +/* MonitorInfo.java - Information on a monitor lock. + 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; + +/** + * Provides information on a monitor lock held by a thread. + * A monitor lock is obtained when a thread enters a synchronized + * block or method. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.6 + */ +public class MonitorInfo + extends LockInfo +{ + + /** + * The stack depth at which the lock was obtained. + */ + private int stackDepth; + + /** + * The stack frame at which the lock was obtained. + */ + private StackTraceElement stackFrame; + + /** + * Constructs a new {@link MonitorInfo} using the specified + * lock class name and identity hash code, and the given + * stack depth and frame. + * + * @param className the class name of the lock object. + * @param identityHashCode the identity hash code of the lock object. + * @param stackDepth the depth of the stack at which the lock + * was obtained. + * @param stackFrame the frame of the stack at which the lock was + * obtained. + * @throws IllegalArgumentException if the stack depth and frame are + * inconsistent i.e. the frame is + * <code>null</code> but the depth is + * ≥ 0, or the frame is not + * <code>null</code> but the depth is + * < 0. + */ + public MonitorInfo(String className, int identityHashCode, int stackDepth, + StackTraceElement stackFrame) + { + super(className, identityHashCode); + if (stackFrame == null && stackDepth >= 0) + throw new IllegalArgumentException("The stack frame is null, but the " + + "stack depth is greater than or equal " + + "to zero."); + if (stackFrame != null && stackDepth < 0) + throw new IllegalArgumentException("The stack frame is not null, but the " + + "stack depth is less than zero."); + this.stackDepth = stackDepth; + this.stackFrame = stackFrame; + } + + /** + * <p> + * Returns a {@link MonitorInfo} 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>className</td><td>java.lang.String</td></tr> + * <tr><td>identityHashCode</td><td>java.lang.Integer</td></tr> + * <tr><td>lockedStackDepth</td><td>java.lang.Integer</td></tr> + * <tr><td>lockedStackFrame</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 MonitorInfo from(CompositeData data) + { + if (data == null) + return null; + CompositeType type = data.getCompositeType(); + ThreadInfo.checkAttribute(type, "ClassName", SimpleType.STRING); + ThreadInfo.checkAttribute(type, "IdentityHashCode", SimpleType.INTEGER); + ThreadInfo.checkAttribute(type, "LockedStackDepth", SimpleType.INTEGER); + ThreadInfo.checkAttribute(type, "LockedStackFrame", + ThreadInfo.getStackTraceType()); + CompositeData frame = (CompositeData) data.get("LockedStackFrame"); + return new MonitorInfo((String) data.get("ClassName"), + (Integer) data.get("IdentityHashCode"), + (Integer) data.get("LockedStackDepth"), + new StackTraceElement((String) frame.get("ClassName"), + (String) frame.get("MethodName"), + (String) frame.get("FileName"), + (Integer) frame.get("LineNumber"))); + } + + /** + * Returns the depth of the stack at which the lock was obtained. + * This works as an index into the array returned by + * {@link ThreadInfo#getStackTrace()}. + * + * @return the depth of the stack at which the lock was obtained, + * or a negative number if this information is unavailable. + */ + public int getLockedStackDepth() + { + return stackDepth; + } + + /** + * Returns the stack frame at which the lock was obtained. + * + * @return the stack frame at which the lock was obtained, + * or <code>null</code> if this informati0on is unavailable. + */ + public StackTraceElement getLockedStackFrame() + { + return stackFrame; + } + +} diff --git a/libjava/classpath/java/lang/management/OperatingSystemMXBean.java b/libjava/classpath/java/lang/management/OperatingSystemMXBean.java new file mode 100644 index 000000000..dcc963ef1 --- /dev/null +++ b/libjava/classpath/java/lang/management/OperatingSystemMXBean.java @@ -0,0 +1,119 @@ +/* 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 system load average for the last minute, or -1 + * if this is unavailable. The availability and calculation + * of the load average is system-dependent, but is usually + * a damped time-dependent average obtained by monitoring the + * number of queued and running processes. It is expected + * that this method will be called frequently to monitor the + * average over time, so it may not be implemented on systems + * where such a call is expensive. + * + * @return the system load average for the last minute, or -1 + * if this is unavailable. + * @since 1.6 + */ + double getSystemLoadAverage(); + + /** + * 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 000000000..1e2aa017f --- /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<String> 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<String,String> 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 000000000..a4ecc76f5 --- /dev/null +++ b/libjava/classpath/java/lang/management/ThreadInfo.java @@ -0,0 +1,895 @@ +/* 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 java.util.Arrays; + +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> + * <li>The current locks held on object monitors by the thread.</li> + * <li>The current locks held on ownable synchronizers by the thread.</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 Thread.State 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; + + /** + * The array of information on monitors locked by the thread. + */ + private MonitorInfo[] lockedMonitors; + + /** + * The array of information on ownable synchronizers locked + * by the thread. + */ + private LockInfo[] lockedSynchronizers; + + /** + * Cache a local reference to the thread management bean. + */ + private static ThreadMXBean bean = null; + + /** + * Cache the {@link javax.management.openmbean.CompositeType} + * for the {@link StackTraceElement}. + */ + private static CompositeType seType; + + /** + * 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) + * @param lockedMonitors an array of {@link MonitorInfo} objects + * representing locks held on object monitors + * by the thread. + * @param lockedSynchronizers an array of {@link LockInfo} objects + * representing locks held on ownable + * synchronizers by the thread. + * + * @since 1.6 + */ + private ThreadInfo(long threadId, String threadName, Thread.State threadState, + long blockedCount, long blockedTime, String lockName, + long lockOwnerId, String lockOwnerName, long waitedCount, + long waitedTime, boolean isInNative, boolean isSuspended, + StackTraceElement[] trace, MonitorInfo[] lockedMonitors, + LockInfo[] lockedSynchronizers) + { + 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; + this.lockedMonitors = lockedMonitors; + this.lockedSynchronizers = lockedSynchronizers; + } + + /** + * 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()); + } + + /** + * Returns the {@link javax.management.openmbean.CompositeType} for + * a {@link StackTraceElement}. + * + * @return the type for the stack trace element. + */ + static CompositeType getStackTraceType() + { + if (seType == null) + try + { + 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 + }); + } + catch (OpenDataException e) + { + throw new IllegalStateException("Something went wrong in creating " + + "the composite data type for the " + + "stack trace element.", e); + } + return seType; + } + + /** + * <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 + { + checkAttribute(type, "StackTrace", + new ArrayType(1, getStackTraceType())); + } + catch (OpenDataException e) + { + throw new IllegalStateException("Something went wrong in creating " + + "the array for the stack trace element.", + e); + } + OpenType foundType = type.getType("LockedMonitors"); + if (foundType != null) + try + { + CompositeType mType = new CompositeType(MonitorInfo.class.getName(), + "Information on a object monitor lock", + new String[] { "ClassName", + "IdentityHashCode", + "LockedStackDepth", + "LockedStackFrame" + }, + new String[] { "Name of the class", + "Identity hash code " + + "of the class", + "Stack depth at time " + + "of lock", + "Stack frame at time " + + "of lock", + }, + new OpenType[] { + SimpleType.STRING, SimpleType.INTEGER, + SimpleType.INTEGER, getStackTraceType() + }); + if (!(foundType.equals(new ArrayType(1, mType)))) + throw new IllegalArgumentException("Field LockedMonitors is not of " + + "type " + mType.getClassName()); + } + catch (OpenDataException e) + { + throw new IllegalStateException("Something went wrong in creating " + + "the composite data type for the " + + "object monitor information array.", e); + } + foundType = type.getType("LockedSynchronizers"); + if (foundType != null) + try + { + CompositeType lType = new CompositeType(LockInfo.class.getName(), + "Information on a lock", + new String[] { "ClassName", + "IdentityHashCode" + }, + new String[] { "Name of the class", + "Identity hash code " + + "of the class" + }, + new OpenType[] { + SimpleType.STRING, SimpleType.INTEGER + }); + if (!(foundType.equals(new ArrayType(1, lType)))) + throw new IllegalArgumentException("Field LockedSynchronizers is not of " + + "type " + lType.getClassName()); + } + catch (OpenDataException e) + { + throw new IllegalStateException("Something went wrong in creating " + + "the composite data type for the " + + "ownable synchronizerinformation array.", 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()); + MonitorInfo[] mInfo; + if (data.containsKey("LockedMonitors")) + { + CompositeData[] dmInfos = (CompositeData[]) data.get("LockedMonitors"); + mInfo = new MonitorInfo[dmInfos.length]; + for (int a = 0; a < dmInfos.length; ++a) + mInfo[a] = MonitorInfo.from(dmInfos[a]); + } + else + mInfo = new MonitorInfo[]{}; + LockInfo[] lInfo; + if (data.containsKey("LockedSynchronizers")) + { + CompositeData[] dlInfos = (CompositeData[]) data.get("LockedSynchronizers"); + lInfo = new LockInfo[dlInfos.length]; + for (int a = 0; a < dlInfos.length; ++a) + lInfo[a] = new LockInfo((String) dlInfos[a].get("ClassName"), + (Integer) dlInfos[a].get("IdentityHashCode")); + } + else + lInfo = new LockInfo[]{}; + return new ThreadInfo(((Long) data.get("ThreadId")).longValue(), + (String) data.get("ThreadName"), + Thread.State.valueOf((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, mInfo, lInfo); + } + + /** + * 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; + } + + /** + * Returns an array of {@link MonitorInfo} objects representing + * information on the locks on object monitors held by the thread. + * If no locks are held, or such information was not requested + * on creating this {@link ThreadInfo} object, a zero-length + * array will be returned. + * + * @return information on object monitors locked by this thread. + */ + public MonitorInfo[] getLockedMonitors() + { + return lockedMonitors; + } + + /** + * Returns an array of {@link LockInfo} objects representing + * information on the locks on ownable synchronizers held by the thread. + * If no locks are held, or such information was not requested + * on creating this {@link ThreadInfo} object, a zero-length + * array will be returned. + * + * @return information on ownable synchronizers locked by this thread. + */ + public LockInfo[] getLockedSynchronizers() + { + return lockedSynchronizers; + } + + /** + * <p> + * Returns a {@link LockInfo} object representing the + * lock on which this thread is blocked. If the thread + * is not blocked, this method returns <code>null</code>. + * </p> + * <p> + * The thread may be blocked due to one of three reasons: + * </p> + * <ol> + * <li>The thread is in the <code>BLOCKED</code> state + * waiting to acquire an object monitor in order to enter + * a synchronized method or block.</li> + * <li>The thread is in the <code>WAITING</code> or + * <code>TIMED_WAITING</code> state due to a call to + * {@link java.lang.Object#wait()}.</li> + * <li>The thread is in the <code>WAITING</code> or + * <code>TIMED_WAITING</code> state due to a call + * to {@link java.util.concurrent.locks.LockSupport#park()}. + * The lock is the return value of + * {@link java.util.concurrent.locks.LockSupport#getBlocker()}.</li> + * </ol> + * + * @return a {@link LockInfo} object representing the lock on + * which the thread is blocked, or <code>null</code> if + * the thread isn't blocked. + * @since 1.6 + * @see #getLockName() + */ + public LockInfo getLockInfo() + { + String lockName = getLockName(); + int at = lockName.indexOf('@'); + return new LockInfo(lockName.substring(0, at), + Integer.decode(lockName.substring(at + 1))); + } + + /** + * <p> + * Returns a {@link java.lang.String} representation of + * the 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. The value is the same as would + * be returned by <code>getLockInfo().toString()</code> + * </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 (!isThreadBlocked()) + 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 (!isThreadBlocked()) + 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 (!isThreadBlocked()) + 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 Thread.State 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 + + (isThreadBlocked() ? + ", lockOwnerId=" + lockOwnerId + + ", lockOwnerName=" + lockOwnerName : "") + + ", lockedMonitors=" + Arrays.toString(lockedMonitors) + + ", lockedSynchronizers=" + Arrays.toString(lockedSynchronizers) + + "]"; + } + + /** + * <p> + * Returns true if the thread is in a blocked state. + * The thread is regarded as blocked if: + * </p> + * <ol> + * <li>The thread is in the <code>BLOCKED</code> state + * waiting to acquire an object monitor in order to enter + * a synchronized method or block.</li> + * <li>The thread is in the <code>WAITING</code> or + * <code>TIMED_WAITING</code> state due to a call to + * {@link java.lang.Object#wait()}.</li> + * <li>The thread is in the <code>WAITING</code> or + * <code>TIMED_WAITING</code> state due to a call + * to {@link java.util.concurrent.locks.LockSupport#park()}. + * The lock is the return value of + * {@link java.util.concurrent.locks.LockSupport#getBlocker()}.</li> + * </ol> + * + * @return true if the thread is blocked. + */ + private boolean isThreadBlocked() + { + return (threadState == Thread.State.BLOCKED || + threadState == Thread.State.WAITING || + threadState == Thread.State.TIMED_WAITING); + } + +} diff --git a/libjava/classpath/java/lang/management/ThreadMXBean.java b/libjava/classpath/java/lang/management/ThreadMXBean.java new file mode 100644 index 000000000..551c53282 --- /dev/null +++ b/libjava/classpath/java/lang/management/ThreadMXBean.java @@ -0,0 +1,642 @@ +/* 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: + * </p> + * <ul> + * <li>the CPU time used by a thread</li> + * <li>thread contention</li> + * <li>object monitor usage</li> + * <li>ownable synchronizer usage</li> + * </ul> + * <p> + * The monitoring of CPU time is further subdivided into + * the monitoring of either just the current thread or all + * threads. The methods + * {@link #isThreadCpuTimeSupported()}, + * {@link #isCurrentThreadCpuTimeSupported()} + * {@link #isThreadContentionMonitoringSupported()}, + * {@link #isObjectMonitorUsageSupported()} and + * {@link #isSynchronizerUsageSupported()} may be + * used to determine whether or not this functionality is + * supported. + * </p> + * <p> + * Furthermore, both time and contention monitoring 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 +{ + + /** + * This method returns information on all live threads at the + * time of execution (some threads may have terminated by the + * time the method completes). This method is simply a shorthand + * for calling {@link #getThreadInfo(long[], boolean, + * boolean)} with the return value of {@link #getAllThreadIds()}. + * + * @param lockedMonitors true if the returned {@link ThreadInfo} + * objects should contain information on + * locked monitors. + * @param lockedSynchronizers true if the returned {@link ThreadInfo} + * objects should contain information + * on locked ownable synchronizers. + * @return an array of {@link ThreadInfo} objects for all live threads. + * @throws SecurityException if a security manager exists and + * denies ManagementPermission("monitor"). + * @throws UnsupportedOperationException if <code>lockedMonitors</code> + * is true, but object monitor + * usage monitoring is not supported + * by the VM, or + * <code>lockedSynchronizers</code> + * is true, but ownable synchronizer + * usage monitoring is not supported + * by the VM. + * @since 1.6 + * @see #getThreadInfo(long[], boolean, boolean) + * @see #getAllThreadIds() + * @see #isObjectMonitorUsageSupported() + * @see #isSynchronizerUsageSupported() + */ + ThreadInfo[] dumpAllThreads(boolean lockedMonitors, + boolean lockedSynchronizers); + + /** + * <p> + * This method obtains a list of threads which are deadlocked + * waiting to obtain monitor or ownable synchronizer ownership. + * This is similar to the behaviour described for + * {@link #getMonitorDeadlockedThreads()}, except this method also + * takes in to account deadlocks involving ownable synchronizers. + * </p> + * <p> + * 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. If only deadlocks involving monitors are of interest, + * then {@link #findMonitorDeadlockedThreads()} should be used in + * preference to this method. + * </p> + * + * @return an array of thread identifiers, corresponding to threads + * which are currently in a deadlocked situation, or + * <code>null</code> if there are no deadlocks. + * @throws SecurityException if a security manager exists and + * denies ManagementPermission("monitor"). + * @throws UnsupportedOperationException if the VM does not support + * the monitoring of ownable + * synchronizer usage. + * @since 1.6 + * @see #findMonitorDeadlockedThreads() + * @see #isSynchronizerUsageSupported() + */ + long[] findDeadlockedThreads(); + + /** + * <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. This method only returns deadlocks involving monitors; + * to include deadlocks involving ownable synchronizers, + * {@link #findDeadlockedThreads()} should be used instead. + * </p> + * + * @return an array of thread identifiers, corresponding to threads + * which are currently in a deadlocked situation, or + * <code>null</code> if there are no deadlocks. + * @throws SecurityException if a security manager exists and + * denies ManagementPermission("monitor"). + * @see #findDeadlockedThreads() + */ + 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 threads with full + * stack trace information and optional synchronization + * information. If <code>lockedMonitors</code> is false, + * or there are no locked monitors for a particular thread, + * then the corresponding {@link ThreadInfo} object will have + * an empty {@link MonitorInfo} array. Likewise, if + * <code>lockedSynchronizers</code> is false, or there are + * no locked ownable synchronizers for a particular thread, + * then the corresponding {@link ThreadInfo} object will have + * an empty {@link LockInfo} array. If both + * <code>lockedMonitors</code> and <code>lockedSynchronizers</code> + * are false, the return value is equivalent to that from + * <code>{@link #getThreadInfo}(ids, Integer.MAX_VALUE)</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. + * @param lockedMonitors true if information on locked monitors + * should be included. + * @param lockedSynchronizers true if information on locked + * ownable synchronizers should be included. + * @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"). + * @throws UnsupportedOperationException if <code>lockedMonitors</code> + * is true, but object monitor + * usage monitoring is not supported + * by the VM, or + * <code>lockedSynchronizers</code> + * is true, but ownable synchronizer + * usage monitoring is not supported + * by the VM. + * @since 1.6 + * @see #isObjectMonitorUsageSupported() + * @see #isSynchronizerUsageSupported() + */ + ThreadInfo[] getThreadInfo(long[] ids, boolean lockedMonitors, + boolean lockedSynchronizers); + + /** + * 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 the virtual machine supports the monitoring + * of object monitor usage. + * + * @return true if the monitoring of object monitor usage + * is supported by the virtual machine. + * @since 1.6 + */ + boolean isObjectMonitorUsageSupported(); + + /** + * Returns true if the virtual machine supports the monitoring + * of ownable synchronizer usage. + * + * @return true if the monitoring of ownable synchronizer usage + * is supported by the virtual machine. + * @since 1.6 + */ + boolean isSynchronizerUsageSupported(); + + /** + * 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 000000000..1b37cc1a5 --- /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> |