001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: package org.apache.harmony.lang.management;
019:
020: import java.lang.management.ManagementPermission;
021: import java.lang.management.MemoryManagerMXBean;
022: import java.lang.management.MemoryUsage;
023: import java.util.LinkedList;
024: import java.util.List;
025:
026: import javax.management.ListenerNotFoundException;
027: import javax.management.MBeanNotificationInfo;
028: import javax.management.Notification;
029: import javax.management.NotificationBroadcasterSupport;
030: import javax.management.NotificationEmitter;
031: import javax.management.NotificationFilter;
032: import javax.management.NotificationListener;
033:
034: /**
035: * Runtime type for {@link MemoryMXBean}.
036: * <p>
037: * Implementation note. This type of bean is both dynamic and a notification
038: * emitter. The dynamic behaviour comes courtesy of the
039: * {@link org.apache.harmony.lang.management.DynamicMXBeanImpl} superclass while the
040: * notifying behaviour uses a delegation approach to a private member that
041: * implements the {@link javax.management.NotificationEmitter} interface.
042: * Because multiple inheritance is not supported in Java it was a toss up which
043: * behaviour would be based on inheritence and which would use delegation. Every
044: * other <code>*MXBeanImpl</code> class in this package inherits from the
045: * abstract base class <code>DynamicMXBeanImpl</code> so that seemed to be the
046: * natural approach for this class too. By choosing not to make this class a
047: * subclass of {@link javax.management.NotificationBroadcasterSupport}, the
048: * protected
049: * <code>handleNotification(javax.management.NotificationListener, javax.management.Notification, java.lang.Object)</code>
050: * method cannot be overridden for any custom notification behaviour. However,
051: * taking the agile mantra of <b>YAGNI </b> to heart, it was decided that the
052: * default implementation of that method will suffice until new requirements
053: * prove otherwise.
054: * </p>
055: *
056: * @since 1.5
057: */
058: public final class MemoryMXBeanImpl extends DynamicMXBeanImpl implements
059: java.lang.management.MemoryMXBean, NotificationEmitter {
060:
061: /**
062: * The delegate for all notification management.
063: */
064: private NotificationBroadcasterSupport notifier = new NotificationBroadcasterSupport();
065:
066: private static MemoryMXBeanImpl instance = new MemoryMXBeanImpl();
067:
068: private List<MemoryManagerMXBean> memoryManagerList;
069:
070: /**
071: * Constructor intentionally private to prevent instantiation by others.
072: * Sets the metadata for this bean.
073: */
074: private MemoryMXBeanImpl() {
075: setMBeanInfo(ManagementUtils
076: .getMBeanInfo(java.lang.management.MemoryMXBean.class
077: .getName()));
078: memoryManagerList = new LinkedList<MemoryManagerMXBean>();
079: createMemoryManagers();
080: }
081:
082: /**
083: * Singleton accessor method.
084: *
085: * @return the <code>ClassLoadingMXBeanImpl</code> singleton.
086: */
087: static MemoryMXBeanImpl getInstance() {
088: return instance;
089: }
090:
091: /**
092: * Instantiates MemoryManagerMXBean and GarbageCollectorMXBean instance(s)
093: * for the current VM configuration and stores them in memoryManagerList.
094: */
095: private native void createMemoryManagers();
096:
097: /**
098: * A helper method called from within the native
099: * {@link #createMemoryManagers()} method to construct new instances of
100: * MemoryManagerMXBean and GarbageCollectorMXBean and add them to the
101: * {@link #memoryManagerList}.
102: *
103: * @param name
104: * the name of the corresponding memory manager
105: * @param internalID
106: * numerical identifier associated with the memory manager for
107: * the benefit of the VM
108: * @param isGC
109: * boolean indication of the memory manager type.
110: * <code>true</code> indicates that the runtime type of the
111: * object to be created is
112: * <code>GarbageCollectorMXBeanImpl</code> while
113: * <code>false</code> indicates a
114: * <code>MemoryManagerMXBeanImpl</code>
115: */
116: @SuppressWarnings("unused")
117: // IMPORTANT: for use by VM
118: private void createMemoryManagerHelper(String name, int internalID,
119: boolean isGC) {
120: if (isGC) {
121: memoryManagerList.add(new GarbageCollectorMXBeanImpl(name,
122: internalID, this ));
123: } else {
124: memoryManagerList.add(new MemoryManagerMXBeanImpl(name,
125: internalID, this ));
126: }
127: }
128:
129: /**
130: * Retrieves the list of memory manager beans in the system.
131: *
132: * @return the list of <code>MemoryManagerMXBean</code> instances
133: */
134: List<MemoryManagerMXBean> getMemoryManagerMXBeans() {
135: return memoryManagerList;
136: }
137:
138: /*
139: * (non-Javadoc)
140: *
141: * @see java.lang.management.MemoryMXBean#gc()
142: */
143: public void gc() {
144: System.gc();
145: }
146:
147: /**
148: * @return an instance of {@link MemoryUsage}which can be interrogated by
149: * the caller.
150: * @see #getHeapMemoryUsage()
151: */
152: private native MemoryUsage getHeapMemoryUsageImpl();
153:
154: /*
155: * (non-Javadoc)
156: *
157: * @see java.lang.management.MemoryMXBean#getHeapMemoryUsage()
158: */
159: public MemoryUsage getHeapMemoryUsage() {
160: return this .getHeapMemoryUsageImpl();
161: }
162:
163: /**
164: * @return an instance of {@link MemoryUsage}which can be interrogated by
165: * the caller.
166: * @see #getNonHeapMemoryUsage()
167: */
168: private native MemoryUsage getNonHeapMemoryUsageImpl();
169:
170: /*
171: * (non-Javadoc)
172: *
173: * @see java.lang.management.MemoryMXBean#getNonHeapMemoryUsage()
174: */
175: public MemoryUsage getNonHeapMemoryUsage() {
176: return this .getNonHeapMemoryUsageImpl();
177: }
178:
179: /**
180: * @return the number of objects awaiting finalization.
181: * @see #getObjectPendingFinalizationCount()
182: */
183: private native int getObjectPendingFinalizationCountImpl();
184:
185: /*
186: * (non-Javadoc)
187: *
188: * @see java.lang.management.MemoryMXBean#getObjectPendingFinalizationCount()
189: */
190: public int getObjectPendingFinalizationCount() {
191: return this .getObjectPendingFinalizationCountImpl();
192: }
193:
194: /**
195: * @return <code>true</code> if verbose output is being produced ;
196: * <code>false</code> otherwise.
197: * @see #isVerbose()
198: */
199: private native boolean isVerboseImpl();
200:
201: /*
202: * (non-Javadoc)
203: *
204: * @see java.lang.management.MemoryMXBean#isVerbose()
205: */
206: public boolean isVerbose() {
207: return this .isVerboseImpl();
208: }
209:
210: /**
211: * @param value
212: * <code>true</code> enables verbose output ;
213: * <code>false</code> disables verbose output.
214: * @see #setVerbose(boolean)
215: */
216: private native void setVerboseImpl(boolean value);
217:
218: /*
219: * (non-Javadoc)
220: *
221: * @see java.lang.management.MemoryMXBean#setVerbose(boolean)
222: */
223: public void setVerbose(boolean value) {
224: SecurityManager security = System.getSecurityManager();
225: if (security != null) {
226: security
227: .checkPermission(new ManagementPermission("control"));
228: }
229: this .setVerboseImpl(value);
230: }
231:
232: /*
233: * (non-Javadoc)
234: *
235: * @see javax.management.NotificationEmitter#removeNotificationListener(javax.management.NotificationListener,
236: * javax.management.NotificationFilter, java.lang.Object)
237: */
238: public void removeNotificationListener(
239: NotificationListener listener, NotificationFilter filter,
240: Object handback) throws ListenerNotFoundException {
241: notifier.removeNotificationListener(listener, filter, handback);
242: }
243:
244: /*
245: * (non-Javadoc)
246: *
247: * @see javax.management.NotificationBroadcaster#addNotificationListener(javax.management.NotificationListener,
248: * javax.management.NotificationFilter, java.lang.Object)
249: */
250: public void addNotificationListener(NotificationListener listener,
251: NotificationFilter filter, Object handback)
252: throws IllegalArgumentException {
253: notifier.addNotificationListener(listener, filter, handback);
254: }
255:
256: /*
257: * (non-Javadoc)
258: *
259: * @see javax.management.NotificationBroadcaster#removeNotificationListener(javax.management.NotificationListener)
260: */
261: public void removeNotificationListener(NotificationListener listener)
262: throws ListenerNotFoundException {
263: notifier.removeNotificationListener(listener);
264: }
265:
266: /*
267: * (non-Javadoc)
268: *
269: * @see javax.management.NotificationBroadcaster#getNotificationInfo()
270: */
271: public MBeanNotificationInfo[] getNotificationInfo() {
272: // We know what kinds of notifications we can emit whereas the
273: // notifier delegate does not. So, for this method, no delegating.
274: // Instead respond using our own metadata.
275: return this .getMBeanInfo().getNotifications();
276: }
277:
278: /*
279: * (non-Javadoc)
280: *
281: * Send notifications to registered listeners. This will be called when
282: * either of the following situations occur: <ol><li> With the method
283: * {@link java.lang.management.MemoryPoolMXBean#isUsageThresholdSupported()}
284: * returning <code> true </code> , a memory pool increases its size and, in
285: * doing so, reaches or exceeds the usage threshold value. In this case the
286: * notification type will be
287: * {@link MemoryNotificationInfo#MEMORY_THRESHOLD_EXCEEDED}. <li> With the
288: * method
289: * {@link java.lang.management.MemoryPoolMXBean#isCollectionUsageThresholdSupported()}
290: * returning <code> true </code> , a garbage-collected memory pool has
291: * reached or surpassed the collection usage threshold value after a system
292: * garbage collection has taken place. In this case the notification type
293: * will be
294: * {@link MemoryNotificationInfo#MEMORY_COLLECTION_THRESHOLD_EXCEEDED}.
295: * </ol>
296: *
297: * @param notification For this type of bean the user data will consist of a
298: * {@link CompositeData}instance that represents a
299: * {@link MemoryNotificationInfo}object.
300: */
301: public void sendNotification(Notification notification) {
302: notifier.sendNotification(notification);
303: }
304: }
|