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 
getMemoryUsage()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 
getPeakMemoryUsage()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 
getCollectMemoryUsage()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      */
JvmMemPoolEntryImpl(MemoryPoolMXBean mp, final int index)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      */
getJvmMemPoolMaxSize()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      */
getJvmMemPoolUsed()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      */
getJvmMemPoolInitSize()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      */
getJvmMemPoolCommitted()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      */
getJvmMemPoolPeakMaxSize()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      */
getJvmMemPoolPeakUsed()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      */
getJvmMemPoolPeakCommitted()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      */
getJvmMemPoolCollectMaxSize()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      */
getJvmMemPoolCollectUsed()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      */
getJvmMemPoolCollectCommitted()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      */
getJvmMemPoolThreshold()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      */
setJvmMemPoolThreshold(Long x)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      */
checkJvmMemPoolThreshold(Long x)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      */
getJvmMemPoolThreshdSupport()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      */
getJvmMemPoolThreshdCount()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      */
getJvmMemPoolCollectThreshold()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      */
setJvmMemPoolCollectThreshold(Long x)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      */
checkJvmMemPoolCollectThreshold(Long x)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
getJvmMemPoolCollectThreshdSupport()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      */
getJvmMemPoolCollectThreshdCount()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 
jvmMemPoolType(MemoryType type)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      */
getJvmMemPoolType()418     public EnumJvmMemPoolType getJvmMemPoolType() throws SnmpStatusException {
419         return jvmMemPoolType(pool.getType());
420     }
421 
422     /**
423      * Getter for the "JvmMemPoolName" variable.
424      */
getJvmMemPoolName()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      */
getJvmMemPoolIndex()432     public Integer getJvmMemPoolIndex() throws SnmpStatusException {
433         return new Integer(jvmMemPoolIndex);
434     }
435 
436 
437     /**
438      * Getter for the "JvmMemPoolState" variable.
439      */
getJvmMemPoolState()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      */
getJvmMemPoolPeakReset()451     public synchronized Long getJvmMemPoolPeakReset()
452         throws SnmpStatusException {
453         return new Long(jvmMemPoolPeakReset);
454     }
455 
456     /**
457      * Setter for the "JvmMemPoolPeakReset" variable.
458      */
setJvmMemPoolPeakReset(Long x)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      */
checkJvmMemPoolPeakReset(Long x)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 }
507