001: /*
002: * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025:
026: package sun.management;
027:
028: import java.lang.management.MemoryMXBean;
029: import java.lang.management.MemoryUsage;
030: import java.lang.management.MemoryNotificationInfo;
031: import java.lang.management.MemoryManagerMXBean;
032: import java.lang.management.MemoryPoolMXBean;
033: import javax.management.ObjectName;
034: import javax.management.MalformedObjectNameException;
035: import javax.management.MBeanNotificationInfo;
036: import javax.management.Notification;
037: import javax.management.NotificationEmitter;
038: import javax.management.NotificationFilter;
039: import javax.management.NotificationListener;
040: import javax.management.ListenerNotFoundException;
041: import javax.management.openmbean.CompositeData;
042: import java.util.List;
043: import java.util.ArrayList;
044: import java.util.ListIterator;
045: import java.util.Collections;
046:
047: /**
048: * Implementation class for the memory subsystem.
049: * Standard and committed hotspot-specific metrics if any.
050: *
051: * ManagementFactory.getMemoryMXBean() returns an instance
052: * of this class.
053: */
054: class MemoryImpl extends NotificationEmitterSupport implements
055: MemoryMXBean {
056:
057: private final VMManagement jvm;
058:
059: private static MemoryPoolMXBean[] pools = null;
060: private static MemoryManagerMXBean[] mgrs = null;
061:
062: /**
063: * Constructor of MemoryImpl class
064: */
065: MemoryImpl(VMManagement vm) {
066: this .jvm = vm;
067: }
068:
069: public int getObjectPendingFinalizationCount() {
070: return sun.misc.VM.getFinalRefCount();
071: }
072:
073: public void gc() {
074: Runtime.getRuntime().gc();
075: }
076:
077: // Need to make a VM call to get coherent value
078: public MemoryUsage getHeapMemoryUsage() {
079: return getMemoryUsage0(true);
080: }
081:
082: public MemoryUsage getNonHeapMemoryUsage() {
083: return getMemoryUsage0(false);
084: }
085:
086: public boolean isVerbose() {
087: return jvm.getVerboseGC();
088: }
089:
090: public void setVerbose(boolean value) {
091: ManagementFactory.checkControlAccess();
092:
093: setVerboseGC(value);
094: }
095:
096: // The current Hotspot implementation does not support
097: // dynamically add or remove memory pools & managers.
098: static synchronized MemoryPoolMXBean[] getMemoryPools() {
099: if (pools == null) {
100: pools = getMemoryPools0();
101: }
102: return pools;
103: }
104:
105: static synchronized MemoryManagerMXBean[] getMemoryManagers() {
106: if (mgrs == null) {
107: mgrs = getMemoryManagers0();
108: }
109: return mgrs;
110: }
111:
112: private static native MemoryPoolMXBean[] getMemoryPools0();
113:
114: private static native MemoryManagerMXBean[] getMemoryManagers0();
115:
116: private native MemoryUsage getMemoryUsage0(boolean heap);
117:
118: private native void setVerboseGC(boolean value);
119:
120: private final static String notifName = "javax.management.Notification";
121: private final static String[] notifTypes = {
122: MemoryNotificationInfo.MEMORY_THRESHOLD_EXCEEDED,
123: MemoryNotificationInfo.MEMORY_COLLECTION_THRESHOLD_EXCEEDED };
124: private final static String[] notifMsgs = {
125: "Memory usage exceeds usage threshold",
126: "Memory usage exceeds collection usage threshold" };
127:
128: private MBeanNotificationInfo[] notifInfo = null;
129:
130: public MBeanNotificationInfo[] getNotificationInfo() {
131: synchronized (this ) {
132: if (notifInfo == null) {
133: notifInfo = new MBeanNotificationInfo[1];
134: notifInfo[0] = new MBeanNotificationInfo(notifTypes,
135: notifName, "Memory Notification");
136: }
137: }
138: return notifInfo;
139: }
140:
141: private static String getNotifMsg(String notifType) {
142: for (int i = 0; i < notifTypes.length; i++) {
143: if (notifType == notifTypes[i]) {
144: return notifMsgs[i];
145: }
146: }
147: return "Unknown message";
148: }
149:
150: private static long seqNumber = 0;
151:
152: private static long getNextSeqNumber() {
153: return ++seqNumber;
154: }
155:
156: private static ObjectName objname = null;
157:
158: private static synchronized ObjectName getObjectName() {
159: if (objname != null)
160: return objname;
161:
162: try {
163: objname = new ObjectName(
164: java.lang.management.ManagementFactory.MEMORY_MXBEAN_NAME);
165: } catch (MalformedObjectNameException e) {
166: // should never reach here
167: throw Util.newInternalError(e);
168: }
169: return objname;
170: }
171:
172: static void createNotification(String notifType, String poolName,
173: MemoryUsage usage, long count) {
174: MemoryImpl mbean = (MemoryImpl) ManagementFactory
175: .getMemoryMXBean();
176: if (!mbean.hasListeners()) {
177: // if no listener is registered.
178: return;
179: }
180: long timestamp = System.currentTimeMillis();
181: String msg = getNotifMsg(notifType);
182: Notification notif = new Notification(notifType,
183: getObjectName(), getNextSeqNumber(), timestamp, msg);
184: MemoryNotificationInfo info = new MemoryNotificationInfo(
185: poolName, usage, count);
186: CompositeData cd = MemoryNotifInfoCompositeData
187: .toCompositeData(info);
188: notif.setUserData(cd);
189: mbean.sendNotification(notif);
190: }
191:
192: }
|