1:
37:
38: package ;
39:
40: import ;
41: import ;
42: import ;
43:
44: import ;
45: import ;
46: import ;
47:
48: import ;
49: import ;
50: import ;
51: import ;
52: import ;
53: import ;
54: import ;
55:
56: import ;
57: import ;
58: import ;
59: import ;
60: import ;
61: import ;
62:
63:
72: public final class MemoryMXBeanImpl
73: extends BeanImpl
74: implements MemoryMXBean, NotificationEmitter
75: {
76:
77: private List listeners;
78:
79: private long notificationCount;
80:
81: public static CompositeType notifType;
82:
83: public static CompositeType usageType;
84:
85: static
86: {
87: try
88: {
89: CompositeType usageType =
90: new CompositeType(MemoryUsage.class.getName(),
91: "Describes the usage levels of a pool",
92: new String[] { "init", "used",
93: "committed", "max"
94: },
95: new String[] { "Initial level",
96: "Used level",
97: "Committed level",
98: "Maximum level"
99: },
100: new OpenType[] {
101: SimpleType.LONG, SimpleType.LONG,
102: SimpleType.LONG, SimpleType.LONG
103: });
104: CompositeType notifType =
105: new CompositeType(MemoryNotificationInfo.class.getName(),
106: "Provides the notification info on memory usage",
107: new String[] { "poolName", "usage", "count" },
108: new String[] { "Name of the memory pool",
109: "Usage level of the memory pool",
110: "Number of times the threshold " +
111: "has been crossed"
112: },
113: new OpenType[] {
114: SimpleType.STRING, usageType, SimpleType.LONG
115: });
116: }
117: catch (OpenDataException e)
118: {
119: throw new IllegalStateException("Something went wrong in creating " +
120: "the composite data types.", e);
121: }
122: }
123:
124:
132: public MemoryMXBeanImpl()
133: throws NotCompliantMBeanException
134: {
135: super(MemoryMXBean.class);
136: listeners = new ArrayList();
137: notificationCount = 0;
138: }
139:
140: public void gc()
141: {
142: System.gc();
143: }
144:
145: public MemoryUsage getHeapMemoryUsage()
146: {
147: return VMMemoryMXBeanImpl.getHeapMemoryUsage();
148: }
149:
150: public MemoryUsage getNonHeapMemoryUsage()
151: {
152: return VMMemoryMXBeanImpl.getNonHeapMemoryUsage();
153: }
154:
155: public int getObjectPendingFinalizationCount()
156: {
157: return VMMemoryMXBeanImpl.getObjectPendingFinalizationCount();
158: }
159:
160: public boolean isVerbose()
161: {
162: return VMMemoryMXBeanImpl.isVerbose();
163: }
164:
165: public void setVerbose(boolean verbose)
166: {
167: checkControlPermissions();
168: VMMemoryMXBeanImpl.setVerbose(verbose);
169: }
170:
171: private class ListenerData
172: {
173: private NotificationListener listener;
174: private NotificationFilter filter;
175: private Object passback;
176:
177: public ListenerData(NotificationListener listener,
178: NotificationFilter filter, Object passback)
179: {
180: this.listener = listener;
181: this.filter = filter;
182: this.passback = passback;
183: }
184:
185: public NotificationListener getListener()
186: {
187: return listener;
188: }
189:
190: public NotificationFilter getFilter()
191: {
192: return filter;
193: }
194:
195: public Object getPassback()
196: {
197: return passback;
198: }
199:
200: public boolean equals(Object obj)
201: {
202: if (obj instanceof ListenerData)
203: {
204: ListenerData data = (ListenerData) obj;
205: return (data.getListener() == listener &&
206: data.getFilter() == filter &&
207: data.getPassback() == passback);
208: }
209: return false;
210: }
211:
212: }
213:
214: public void addNotificationListener(NotificationListener listener,
215: NotificationFilter filter,
216: Object passback)
217: {
218: if (listener == null)
219: throw new IllegalArgumentException("Null listener added to bean.");
220: listeners.add(new ListenerData(listener, filter, passback));
221: }
222:
223: public MBeanNotificationInfo[] getNotificationInfo()
224: {
225: return new MBeanNotificationInfo[]
226: {
227: new MBeanNotificationInfo(new String[]
228: {
229: MemoryNotificationInfo.MEMORY_COLLECTION_THRESHOLD_EXCEEDED,
230: MemoryNotificationInfo.MEMORY_THRESHOLD_EXCEEDED
231: },
232: Notification.class.getName(),
233: "Memory Usage Notifications")
234: };
235: }
236:
237: public void removeNotificationListener(NotificationListener listener)
238: throws ListenerNotFoundException
239: {
240: Iterator it = listeners.iterator();
241: boolean foundOne = false;
242: while (it.hasNext())
243: {
244: ListenerData data = (ListenerData) it.next();
245: if (data.getListener() == listener)
246: {
247: it.remove();
248: foundOne = true;
249: }
250: }
251: if (!foundOne)
252: throw new ListenerNotFoundException("The specified listener, " + listener +
253: "is not registered with this bean.");
254: }
255:
256: public void removeNotificationListener(NotificationListener listener,
257: NotificationFilter filter,
258: Object passback)
259: throws ListenerNotFoundException
260: {
261: if (!(listeners.remove(new ListenerData(listener, filter, passback))))
262: {
263: throw new ListenerNotFoundException("The specified listener, " + listener +
264: " with filter " + filter +
265: "and passback " + passback +
266: ", is not registered with this bean.");
267: }
268: }
269:
270: void fireNotification(String type, String poolName, long init, long used,
271: long committed, long max, long count)
272: {
273: Notification notif = new Notification(type, this, notificationCount);
274: MemoryUsage usage = new MemoryUsage(init, used, committed, max);
275: CompositeData data;
276: try
277: {
278: data = new CompositeDataSupport(notifType,
279: new String[] {
280: "poolName", "usage", "count"
281: },
282: new Object[] {
283: poolName, usage, Long.valueOf(count)
284: });
285: }
286: catch (OpenDataException e)
287: {
288: throw new IllegalStateException("Something went wrong in creating " +
289: "the composite data instance.", e);
290: }
291: notif.setUserData(data);
292: Iterator it = listeners.iterator();
293: while (it.hasNext())
294: {
295: ListenerData ldata = (ListenerData) it.next();
296: NotificationFilter filter = ldata.getFilter();
297: if (filter == null || filter.isNotificationEnabled(notif))
298: ldata.getListener().handleNotification(notif, ldata.getPassback());
299: }
300: ++notificationCount;
301: }
302:
303: void fireThresholdExceededNotification(String poolName, long init,
304: long used, long committed,
305: long max, long count)
306: {
307: fireNotification(MemoryNotificationInfo.MEMORY_THRESHOLD_EXCEEDED,
308: poolName, init, used, committed, max, count);
309: }
310:
311: void fireCollectionThresholdExceededNotification(String poolName,
312: long init,
313: long used,
314: long committed,
315: long max,
316: long count)
317: {
318: fireNotification(MemoryNotificationInfo.MEMORY_COLLECTION_THRESHOLD_EXCEEDED,
319: poolName, init, used, committed, max, count);
320: }
321:
322: }