1 /*
   2  * Copyright (c) 2003, 2008, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 package sun.management.snmp.jvminstr;
  26 
  27 // java imports
  28 //
  29 import java.util.Map;
  30 
  31 // jmx imports
  32 //
  33 import com.sun.jmx.snmp.SnmpStatusException;
  34 import com.sun.jmx.snmp.SnmpDefinitions;
  35 
  36 // jdmk imports
  37 //
  38 
  39 import java.lang.management.MemoryUsage;
  40 import java.lang.management.MemoryType;
  41 import java.lang.management.MemoryPoolMXBean;
  42 
  43 import sun.management.snmp.jvmmib.JvmMemPoolEntryMBean;
  44 import sun.management.snmp.jvmmib.EnumJvmMemPoolState;
  45 import sun.management.snmp.jvmmib.EnumJvmMemPoolType;
  46 import sun.management.snmp.jvmmib.EnumJvmMemPoolThreshdSupport;
  47 import sun.management.snmp.jvmmib.EnumJvmMemPoolCollectThreshdSupport;
  48 import sun.management.snmp.util.MibLogger;
  49 import sun.management.snmp.util.JvmContextFactory;
  50 
  51 /**
  52  * The class is used for implementing the "JvmMemPoolEntry" group.
  53  */
  54 public class JvmMemPoolEntryImpl implements JvmMemPoolEntryMBean {
  55 
  56     /**
  57      * Variable for storing the value of "JvmMemPoolIndex".
  58      *
  59      * "An index value opaquely computed by the agent which uniquely
  60      * identifies a row in the jvmMemPoolTable.
  61      * "
  62      *
  63      */
  64     final protected int jvmMemPoolIndex;
  65 
  66 
  67     final static String memoryTag = "jvmMemPoolEntry.getUsage";
  68     final static String peakMemoryTag = "jvmMemPoolEntry.getPeakUsage";
  69     final static String collectMemoryTag =
  70         "jvmMemPoolEntry.getCollectionUsage";
  71     final static MemoryUsage ZEROS = new MemoryUsage(0,0,0,0);
  72 
  73     final String entryMemoryTag;
  74     final String entryPeakMemoryTag;
  75     final String entryCollectMemoryTag;
  76 
  77     MemoryUsage getMemoryUsage() {
  78         try {
  79             final Map<Object, Object> m = JvmContextFactory.getUserData();
  80 
  81             if (m != null) {
  82                 final MemoryUsage cached = (MemoryUsage)
  83                     m.get(entryMemoryTag);
  84                 if (cached != null) {
  85                     log.debug("getMemoryUsage",entryMemoryTag+
  86                           " found in cache.");
  87                     return cached;
  88                 }
  89 
  90                 MemoryUsage u = pool.getUsage();
  91                 if (u == null) u = ZEROS;
  92 
  93                 m.put(entryMemoryTag,u);
  94                 return u;
  95             }
  96             // Should never come here.
  97             // Log error!
  98             log.trace("getMemoryUsage", "ERROR: should never come here!");
  99             return pool.getUsage();
 100         } catch (RuntimeException x) {
 101             log.trace("getMemoryUsage",
 102                   "Failed to get MemoryUsage: " + x);
 103             log.debug("getMemoryUsage",x);
 104             throw x;
 105         }
 106 
 107     }
 108 
 109     MemoryUsage getPeakMemoryUsage() {
 110         try {
 111             final Map<Object, Object> m = JvmContextFactory.getUserData();
 112 
 113             if (m != null) {
 114                 final MemoryUsage cached = (MemoryUsage)
 115                     m.get(entryPeakMemoryTag);
 116                 if (cached != null) {
 117                     if (log.isDebugOn())
 118                         log.debug("getPeakMemoryUsage",
 119                               entryPeakMemoryTag + " found in cache.");
 120                     return cached;
 121                 }
 122 
 123                 MemoryUsage u = pool.getPeakUsage();
 124                 if (u == null) u = ZEROS;
 125 
 126                 m.put(entryPeakMemoryTag,u);
 127                 return u;
 128             }
 129             // Should never come here.
 130             // Log error!
 131             log.trace("getPeakMemoryUsage", "ERROR: should never come here!");
 132             return ZEROS;
 133         } catch (RuntimeException x) {
 134             log.trace("getPeakMemoryUsage",
 135                   "Failed to get MemoryUsage: " + x);
 136             log.debug("getPeakMemoryUsage",x);
 137             throw x;
 138         }
 139 
 140     }
 141 
 142     MemoryUsage getCollectMemoryUsage() {
 143         try {
 144             final Map<Object, Object> m = JvmContextFactory.getUserData();
 145 
 146             if (m != null) {
 147                 final MemoryUsage cached = (MemoryUsage)
 148                     m.get(entryCollectMemoryTag);
 149                 if (cached != null) {
 150                     if (log.isDebugOn())
 151                         log.debug("getCollectMemoryUsage",
 152                                   entryCollectMemoryTag + " found in cache.");
 153                     return cached;
 154                 }
 155 
 156                 MemoryUsage u = pool.getCollectionUsage();
 157                 if (u == null) u = ZEROS;
 158 
 159                 m.put(entryCollectMemoryTag,u);
 160                 return u;
 161             }
 162             // Should never come here.
 163             // Log error!
 164             log.trace("getCollectMemoryUsage",
 165                       "ERROR: should never come here!");
 166             return ZEROS;
 167         } catch (RuntimeException x) {
 168             log.trace("getPeakMemoryUsage",
 169                   "Failed to get MemoryUsage: " + x);
 170             log.debug("getPeakMemoryUsage",x);
 171             throw x;
 172         }
 173 
 174     }
 175 
 176     final MemoryPoolMXBean pool;
 177 
 178     /**
 179      * Constructor for the "JvmMemPoolEntry" group.
 180      */
 181     public JvmMemPoolEntryImpl(MemoryPoolMXBean mp, final int index) {
 182         this.pool=mp;
 183         this.jvmMemPoolIndex = index;
 184         this.entryMemoryTag = memoryTag + "." + index;
 185         this.entryPeakMemoryTag = peakMemoryTag + "." + index;
 186         this.entryCollectMemoryTag = collectMemoryTag + "." + index;
 187     }
 188 
 189     /**
 190      * Getter for the "JvmMemPoolMaxSize" variable.
 191      */
 192     public Long getJvmMemPoolMaxSize() throws SnmpStatusException {
 193         final long val = getMemoryUsage().getMax();
 194         if (val > -1) return  new Long(val);
 195         else return JvmMemoryImpl.Long0;
 196     }
 197 
 198     /**
 199      * Getter for the "JvmMemPoolUsed" variable.
 200      */
 201     public Long getJvmMemPoolUsed() throws SnmpStatusException {
 202         final long val = getMemoryUsage().getUsed();
 203         if (val > -1) return  new Long(val);
 204         else return JvmMemoryImpl.Long0;
 205     }
 206 
 207     /**
 208      * Getter for the "JvmMemPoolInitSize" variable.
 209      */
 210     public Long getJvmMemPoolInitSize() throws SnmpStatusException {
 211         final long val = getMemoryUsage().getInit();
 212         if (val > -1) return  new Long(val);
 213         else return JvmMemoryImpl.Long0;
 214     }
 215 
 216     /**
 217      * Getter for the "JvmMemPoolCommitted" variable.
 218      */
 219     public Long getJvmMemPoolCommitted() throws SnmpStatusException {
 220         final long val = getMemoryUsage().getCommitted();
 221         if (val > -1) return  new Long(val);
 222         else return JvmMemoryImpl.Long0;
 223     }
 224 
 225     /**
 226      * Getter for the "JvmMemPoolPeakMaxSize" variable.
 227      */
 228     public Long getJvmMemPoolPeakMaxSize() throws SnmpStatusException {
 229         final long val = getPeakMemoryUsage().getMax();
 230         if (val > -1) return  new Long(val);
 231         else return JvmMemoryImpl.Long0;
 232     }
 233 
 234     /**
 235      * Getter for the "JvmMemPoolPeakUsed" variable.
 236      */
 237     public Long getJvmMemPoolPeakUsed() throws SnmpStatusException {
 238         final long val = getPeakMemoryUsage().getUsed();
 239         if (val > -1) return  new Long(val);
 240         else return JvmMemoryImpl.Long0;
 241     }
 242 
 243     /**
 244      * Getter for the "JvmMemPoolPeakCommitted" variable.
 245      */
 246     public Long getJvmMemPoolPeakCommitted() throws SnmpStatusException {
 247         final long val = getPeakMemoryUsage().getCommitted();
 248         if (val > -1) return  new Long(val);
 249         else return JvmMemoryImpl.Long0;
 250     }
 251 
 252     /**
 253      * Getter for the "JvmMemPoolCollectMaxSize" variable.
 254      */
 255     public Long getJvmMemPoolCollectMaxSize() throws SnmpStatusException {
 256         final long val = getCollectMemoryUsage().getMax();
 257         if (val > -1) return  new Long(val);
 258         else return JvmMemoryImpl.Long0;
 259     }
 260 
 261     /**
 262      * Getter for the "JvmMemPoolCollectUsed" variable.
 263      */
 264     public Long getJvmMemPoolCollectUsed() throws SnmpStatusException {
 265         final long val = getCollectMemoryUsage().getUsed();
 266         if (val > -1) return  new Long(val);
 267         else return JvmMemoryImpl.Long0;
 268     }
 269 
 270     /**
 271      * Getter for the "JvmMemPoolCollectCommitted" variable.
 272      */
 273     public Long getJvmMemPoolCollectCommitted() throws SnmpStatusException {
 274         final long val = getCollectMemoryUsage().getCommitted();
 275         if (val > -1) return  new Long(val);
 276         else return JvmMemoryImpl.Long0;
 277     }
 278 
 279     /**
 280      * Getter for the "JvmMemPoolThreshold" variable.
 281      */
 282     public Long getJvmMemPoolThreshold() throws SnmpStatusException {
 283         if (!pool.isUsageThresholdSupported())
 284             return JvmMemoryImpl.Long0;
 285         final long val = pool.getUsageThreshold();
 286         if (val > -1) return  new Long(val);
 287         else return JvmMemoryImpl.Long0;
 288     }
 289 
 290     /**
 291      * Setter for the "JvmMemPoolThreshold" variable.
 292      */
 293     public void setJvmMemPoolThreshold(Long x) throws SnmpStatusException {
 294         final long val = x.longValue();
 295         if (val < 0 )
 296             throw new SnmpStatusException(SnmpDefinitions.snmpRspWrongValue);
 297         // This should never throw an exception has the checks have
 298         // already been performed in checkJvmMemPoolThreshold().
 299         //
 300         pool.setUsageThreshold(val);
 301     }
 302 
 303     /**
 304      * Checker for the "JvmMemPoolThreshold" variable.
 305      */
 306     public void checkJvmMemPoolThreshold(Long x) throws SnmpStatusException {
 307         // if threshold is -1, it means that low memory detection is not
 308         // supported.
 309 
 310         if (!pool.isUsageThresholdSupported())
 311             throw new
 312                 SnmpStatusException(SnmpDefinitions.snmpRspInconsistentValue);
 313         final long val = x.longValue();
 314         if (val < 0 )
 315             throw new SnmpStatusException(SnmpDefinitions.snmpRspWrongValue);
 316     }
 317 
 318     /**
 319      * Getter for the "JvmMemPoolThreshdSupport" variable.
 320      */
 321     public EnumJvmMemPoolThreshdSupport getJvmMemPoolThreshdSupport()
 322         throws SnmpStatusException {
 323         if (pool.isUsageThresholdSupported())
 324             return EnumJvmMemPoolThreshdSupported;
 325         else
 326             return EnumJvmMemPoolThreshdUnsupported;
 327     }
 328 
 329     /**
 330      * Getter for the "JvmMemPoolThreshdCount" variable.
 331      */
 332     public Long getJvmMemPoolThreshdCount()
 333         throws SnmpStatusException {
 334         if (!pool.isUsageThresholdSupported())
 335             return JvmMemoryImpl.Long0;
 336         final long val = pool.getUsageThresholdCount();
 337         if (val > -1) return  new Long(val);
 338         else return JvmMemoryImpl.Long0;
 339     }
 340 
 341     /**
 342      * Getter for the "JvmMemPoolCollectThreshold" variable.
 343      */
 344     public Long getJvmMemPoolCollectThreshold() throws SnmpStatusException {
 345         if (!pool.isCollectionUsageThresholdSupported())
 346             return JvmMemoryImpl.Long0;
 347         final long val = pool.getCollectionUsageThreshold();
 348         if (val > -1) return  new Long(val);
 349         else return JvmMemoryImpl.Long0;
 350     }
 351 
 352     /**
 353      * Setter for the "JvmMemPoolCollectThreshold" variable.
 354      */
 355     public void setJvmMemPoolCollectThreshold(Long x)
 356         throws SnmpStatusException {
 357         final long val = x.longValue();
 358         if (val < 0 )
 359             throw new SnmpStatusException(SnmpDefinitions.snmpRspWrongValue);
 360         // This should never throw an exception has the checks have
 361         // already been performed in checkJvmMemPoolCollectThreshold().
 362         //
 363         pool.setCollectionUsageThreshold(val);
 364     }
 365 
 366     /**
 367      * Checker for the "JvmMemPoolCollectThreshold" variable.
 368      */
 369     public void checkJvmMemPoolCollectThreshold(Long x)
 370         throws SnmpStatusException {
 371         // if threshold is -1, it means that low memory detection is not
 372         // supported.
 373 
 374         if (!pool.isCollectionUsageThresholdSupported())
 375             throw new
 376                 SnmpStatusException(SnmpDefinitions.snmpRspInconsistentValue);
 377         final long val = x.longValue();
 378         if (val < 0 )
 379             throw new SnmpStatusException(SnmpDefinitions.snmpRspWrongValue);
 380     }
 381 
 382     /**
 383      * Getter for the "JvmMemPoolThreshdSupport" variable.
 384      */
 385     public EnumJvmMemPoolCollectThreshdSupport
 386         getJvmMemPoolCollectThreshdSupport()
 387         throws SnmpStatusException {
 388         if (pool.isCollectionUsageThresholdSupported())
 389             return EnumJvmMemPoolCollectThreshdSupported;
 390         else
 391             return EnumJvmMemPoolCollectThreshdUnsupported;
 392     }
 393 
 394     /**
 395      * Getter for the "JvmMemPoolCollectThreshdCount" variable.
 396      */
 397     public Long getJvmMemPoolCollectThreshdCount()
 398         throws SnmpStatusException {
 399         if (!pool.isCollectionUsageThresholdSupported())
 400             return JvmMemoryImpl.Long0;
 401         final long val = pool.getCollectionUsageThresholdCount();
 402         if (val > -1) return  new Long(val);
 403         else return JvmMemoryImpl.Long0;
 404     }
 405 
 406     public static EnumJvmMemPoolType jvmMemPoolType(MemoryType type)
 407         throws SnmpStatusException {
 408         if (type.equals(MemoryType.HEAP))
 409             return  EnumJvmMemPoolTypeHeap;
 410         else if (type.equals(MemoryType.NON_HEAP))
 411             return EnumJvmMemPoolTypeNonHeap;
 412         throw new SnmpStatusException(SnmpStatusException.snmpRspWrongValue);
 413     }
 414 
 415     /**
 416      * Getter for the "JvmMemPoolType" variable.
 417      */
 418     public EnumJvmMemPoolType getJvmMemPoolType() throws SnmpStatusException {
 419         return jvmMemPoolType(pool.getType());
 420     }
 421 
 422     /**
 423      * Getter for the "JvmMemPoolName" variable.
 424      */
 425     public String getJvmMemPoolName() throws SnmpStatusException {
 426         return JVM_MANAGEMENT_MIB_IMPL.validJavaObjectNameTC(pool.getName());
 427     }
 428 
 429     /**
 430      * Getter for the "JvmMemPoolIndex" variable.
 431      */
 432     public Integer getJvmMemPoolIndex() throws SnmpStatusException {
 433         return new Integer(jvmMemPoolIndex);
 434     }
 435 
 436 
 437     /**
 438      * Getter for the "JvmMemPoolState" variable.
 439      */
 440     public EnumJvmMemPoolState getJvmMemPoolState()
 441         throws SnmpStatusException {
 442         if (pool.isValid())
 443             return JvmMemPoolStateValid;
 444         else
 445             return JvmMemPoolStateInvalid;
 446     }
 447 
 448     /**
 449      * Getter for the "JvmMemPoolPeakReset" variable.
 450      */
 451     public synchronized Long getJvmMemPoolPeakReset()
 452         throws SnmpStatusException {
 453         return new Long(jvmMemPoolPeakReset);
 454     }
 455 
 456     /**
 457      * Setter for the "JvmMemPoolPeakReset" variable.
 458      */
 459     public synchronized void setJvmMemPoolPeakReset(Long x)
 460         throws SnmpStatusException {
 461         final long l = x.longValue();
 462         if (l > jvmMemPoolPeakReset) {
 463             final long stamp = System.currentTimeMillis();
 464             pool.resetPeakUsage();
 465             jvmMemPoolPeakReset = stamp;
 466             log.debug("setJvmMemPoolPeakReset",
 467                       "jvmMemPoolPeakReset="+stamp);
 468         }
 469     }
 470 
 471     /**
 472      * Checker for the "JvmMemPoolPeakReset" variable.
 473      */
 474     public void checkJvmMemPoolPeakReset(Long x) throws SnmpStatusException {
 475     }
 476 
 477     /* Last time peak usage was reset */
 478     private long jvmMemPoolPeakReset = 0;
 479 
 480     private final static EnumJvmMemPoolState JvmMemPoolStateValid =
 481         new EnumJvmMemPoolState("valid");
 482     private final static EnumJvmMemPoolState JvmMemPoolStateInvalid =
 483         new EnumJvmMemPoolState("invalid");
 484 
 485     private static final EnumJvmMemPoolType EnumJvmMemPoolTypeHeap =
 486         new EnumJvmMemPoolType("heap");
 487     private static final EnumJvmMemPoolType EnumJvmMemPoolTypeNonHeap =
 488         new EnumJvmMemPoolType("nonheap");
 489 
 490     private static final EnumJvmMemPoolThreshdSupport
 491         EnumJvmMemPoolThreshdSupported =
 492         new EnumJvmMemPoolThreshdSupport("supported");
 493     private static final EnumJvmMemPoolThreshdSupport
 494         EnumJvmMemPoolThreshdUnsupported =
 495         new EnumJvmMemPoolThreshdSupport("unsupported");
 496 
 497     private static final EnumJvmMemPoolCollectThreshdSupport
 498         EnumJvmMemPoolCollectThreshdSupported =
 499         new EnumJvmMemPoolCollectThreshdSupport("supported");
 500     private static final EnumJvmMemPoolCollectThreshdSupport
 501         EnumJvmMemPoolCollectThreshdUnsupported=
 502         new EnumJvmMemPoolCollectThreshdSupport("unsupported");
 503 
 504 
 505     static final MibLogger log = new MibLogger(JvmMemPoolEntryImpl.class);
 506 }