OSDN Git Service

Merged gcj-eclipse branch to trunk.
[pf3gnuchains/gcc-fork.git] / libjava / classpath / gnu / java / lang / management / MemoryMXBeanImpl.java
1 /* MemoryMXBeanImpl.java - Implementation of a memory bean
2    Copyright (C) 2006 Free Software Foundation
3
4 This file is part of GNU Classpath.
5
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING.  If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 USA.
20
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library.  Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
25
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module.  An independent module is a module which is not derived from
33 or based on this library.  If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so.  If you do not wish to do so, delete this
36 exception statement from your version. */
37
38 package gnu.java.lang.management;
39
40 import gnu.classpath.ListenerData;
41
42 import java.lang.management.MemoryMXBean;
43 import java.lang.management.MemoryNotificationInfo;
44 import java.lang.management.MemoryUsage;
45
46 import java.util.ArrayList;
47 import java.util.Iterator;
48 import java.util.List;
49
50 import javax.management.ListenerNotFoundException;
51 import javax.management.MBeanNotificationInfo;
52 import javax.management.NotCompliantMBeanException;
53 import javax.management.Notification;
54 import javax.management.NotificationEmitter;
55 import javax.management.NotificationFilter;
56 import javax.management.NotificationListener;
57
58 import javax.management.openmbean.CompositeData;
59 import javax.management.openmbean.CompositeDataSupport;
60 import javax.management.openmbean.CompositeType;
61 import javax.management.openmbean.OpenDataException;
62 import javax.management.openmbean.OpenType;
63 import javax.management.openmbean.SimpleType;
64
65 /**
66  * Provides access to information about the memory 
67  * management of the current invocation of the virtual
68  * machine.  Instances of this bean are obtained by calling
69  * {@link ManagementFactory#getMemoryMXBean()}.
70  *
71  * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
72  * @since 1.5
73  */
74 public final class MemoryMXBeanImpl
75   extends BeanImpl
76   implements MemoryMXBean, NotificationEmitter
77 {
78
79   private List listeners;
80
81   private long notificationCount;
82
83   public static CompositeType notifType;
84
85   public static CompositeType usageType;
86
87   static
88   {
89     try
90       {
91         CompositeType usageType = 
92           new CompositeType(MemoryUsage.class.getName(),
93                             "Describes the usage levels of a pool",
94                             new String[] { "init", "used",
95                                            "committed", "max"
96                             },
97                             new String[] { "Initial level",
98                                            "Used level",
99                                            "Committed level",
100                                            "Maximum level"
101                             },
102                             new OpenType[] {
103                               SimpleType.LONG, SimpleType.LONG,
104                               SimpleType.LONG, SimpleType.LONG
105                             });
106         CompositeType notifType =
107           new CompositeType(MemoryNotificationInfo.class.getName(),
108                             "Provides the notification info on memory usage",
109                             new String[] { "poolName", "usage", "count" },
110                             new String[] { "Name of the memory pool",
111                                            "Usage level of the memory pool",
112                                            "Number of times the threshold " +
113                                            "has been crossed"
114                             },
115                             new OpenType[] {
116                               SimpleType.STRING, usageType, SimpleType.LONG 
117                             });
118           }
119         catch (OpenDataException e)
120           {
121             throw new IllegalStateException("Something went wrong in creating " +
122                                             "the composite data types.", e);
123           }
124   }
125
126   /**
127    * Constructs a new <code>MemoryMXBeanImpl</code>.
128    *
129    * @throws NotCompliantMBeanException if this class doesn't implement
130    *                                    the interface or a method appears
131    *                                    in the interface that doesn't comply
132    *                                    with the naming conventions.
133    */
134   public MemoryMXBeanImpl()
135     throws NotCompliantMBeanException
136   {
137     super(MemoryMXBean.class);
138     listeners = new ArrayList();
139     notificationCount = 0;
140   }
141
142   public void gc()
143   {
144     System.gc();
145   }
146
147   public MemoryUsage getHeapMemoryUsage()
148   {
149     return VMMemoryMXBeanImpl.getHeapMemoryUsage();
150   }
151
152   public MemoryUsage getNonHeapMemoryUsage()
153   {
154     return VMMemoryMXBeanImpl.getNonHeapMemoryUsage();
155   }
156
157   public int getObjectPendingFinalizationCount()
158   {
159     return VMMemoryMXBeanImpl.getObjectPendingFinalizationCount();
160   }
161
162   public boolean isVerbose()
163   {
164     return VMMemoryMXBeanImpl.isVerbose();
165   }
166
167   public void setVerbose(boolean verbose)
168   {
169     checkControlPermissions();
170     VMMemoryMXBeanImpl.setVerbose(verbose);
171   }
172
173   public void addNotificationListener(NotificationListener listener,
174                                       NotificationFilter filter,
175                                       Object passback)
176   {
177     if (listener == null)
178       throw new IllegalArgumentException("Null listener added to bean.");
179     listeners.add(new ListenerData(listener, filter, passback));
180   }
181
182   public MBeanNotificationInfo[] getNotificationInfo()
183   {
184     return new MBeanNotificationInfo[]
185       {
186         new MBeanNotificationInfo(new String[]
187           {
188             MemoryNotificationInfo.MEMORY_COLLECTION_THRESHOLD_EXCEEDED,
189             MemoryNotificationInfo.MEMORY_THRESHOLD_EXCEEDED
190           },
191                                   Notification.class.getName(), 
192                                   "Memory Usage Notifications")
193       };
194   }
195
196   public void removeNotificationListener(NotificationListener listener)
197     throws ListenerNotFoundException
198   {
199     Iterator it = listeners.iterator();
200     boolean foundOne = false;
201     while (it.hasNext())
202       {
203         ListenerData data = (ListenerData) it.next();
204         if (data.getListener() == listener)
205           {
206             it.remove();
207             foundOne = true;
208           }
209       }
210     if (!foundOne)
211       throw new ListenerNotFoundException("The specified listener, " + listener +
212                                           "is not registered with this bean.");
213   }
214
215   public void removeNotificationListener(NotificationListener listener,
216                                          NotificationFilter filter,
217                                          Object passback)
218     throws ListenerNotFoundException
219   {
220     if (!(listeners.remove(new ListenerData(listener, filter, passback))))
221       {
222         throw new ListenerNotFoundException("The specified listener, " + listener +
223                                             " with filter " + filter + 
224                                             "and passback " + passback + 
225                                             ", is not registered with this bean.");
226       }
227   }
228
229   void fireNotification(String type, String poolName, long init, long used,
230                         long committed, long max, long count)
231   {
232     Notification notif = new Notification(type, this, notificationCount);
233     MemoryUsage usage = new MemoryUsage(init, used, committed, max);
234     CompositeData data;
235     try
236       {
237         data = new CompositeDataSupport(notifType, 
238                                         new String[] {
239                                           "poolName", "usage", "count"
240                                         },
241                                         new Object[] {
242                                           poolName, usage, Long.valueOf(count)
243                                         });
244       }
245     catch (OpenDataException e)
246       {
247         throw new IllegalStateException("Something went wrong in creating " +
248                                         "the composite data instance.", e);
249       }
250     notif.setUserData(data);
251     Iterator it = listeners.iterator();
252     while (it.hasNext())
253       {
254         ListenerData ldata = (ListenerData) it.next();
255         NotificationFilter filter = ldata.getFilter();
256         if (filter == null || filter.isNotificationEnabled(notif))
257           ldata.getListener().handleNotification(notif, ldata.getPassback());
258       }
259     ++notificationCount;
260   }
261
262   void fireThresholdExceededNotification(String poolName, long init,
263                                          long used, long committed,
264                                          long max, long count)
265   {
266     fireNotification(MemoryNotificationInfo.MEMORY_THRESHOLD_EXCEEDED,
267                      poolName, init, used, committed, max, count);
268   }
269
270   void fireCollectionThresholdExceededNotification(String poolName,
271                                                    long init,
272                                                    long used,
273                                                    long committed,
274                                                    long max,
275                                                    long count)
276   {
277     fireNotification(MemoryNotificationInfo.MEMORY_COLLECTION_THRESHOLD_EXCEEDED,
278                      poolName, init, used, committed, max, count);
279   }
280
281 }