Source for gnu.java.lang.management.MemoryMXBeanImpl

   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.javax.management.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: }