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: }