blob: 774db16dc285ef65cca4831dbd050d4a8172413c [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 2003-2006 Sun Microsystems, Inc. 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. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25package sun.management.snmp.jvminstr;
26
27// jmx imports
28//
29import javax.management.MBeanServer;
30import com.sun.jmx.snmp.SnmpStatusException;
31import com.sun.jmx.snmp.SnmpDefinitions;
32
33// jdmk imports
34//
35import com.sun.jmx.snmp.agent.SnmpMib;
36
37import java.util.Map;
38import java.lang.management.ManagementFactory;
39import java.lang.management.MemoryUsage;
40import java.lang.management.MemoryType;
41import java.lang.management.MemoryMXBean;
42import javax.management.openmbean.CompositeData;
43
44import sun.management.snmp.jvmmib.JvmMemoryMBean;
45import sun.management.snmp.jvmmib.EnumJvmMemoryGCCall;
46import sun.management.snmp.jvmmib.EnumJvmMemoryGCVerboseLevel;
47import sun.management.snmp.util.MibLogger;
48import sun.management.snmp.util.JvmContextFactory;
49
50/**
51 * The class is used for implementing the "JvmMemory" group.
52 */
53public class JvmMemoryImpl implements JvmMemoryMBean {
54
55 /**
56 * Variable for storing the value of "JvmMemoryGCCall".
57 *
58 * "This object makes it possible to remotelly trigger the
59 * Garbage Collector in the JVM.
60 *
61 * This object's syntax is an enumeration which defines:
62 *
63 * * Two state values, that can be returned from a GET request:
64 *
65 * unsupported(1): means that remote invocation of gc() is not
66 * supported by the SNMP agent.
67 * supported(2) : means that remote invocation of gc() is supported
68 * by the SNMP agent.
69 *
70 * * One action value, that can be provided in a SET request to
71 * trigger the garbage collector:
72 *
73 * start(3) : means that a manager wishes to trigger
74 * garbage collection.
75 *
76 * * Two result value, that will be returned as a result of a
77 * SET request when remote invocation of gc is supported
78 * by the SNMP agent:
79 *
80 * started(4) : means that garbage collection was
81 * successfully triggered. It does not mean
82 * however that the action was successfullly
83 * completed: gc might still be running when
84 * this value is returned.
85 * failed(5) : means that garbage collection couldn't be
86 * triggered.
87 *
88 * * If remote invocation is not supported by the SNMP agent, then
89 * unsupported(1) will always be returned as a result of either
90 * a GET request, or a SET request with start(3) as input value.
91 *
92 * * If a SET request with anything but start(3) is received, then
93 * the agent will return a wrongValue error.
94 *
95 * See java.management.MemoryMXBean.gc()
96 * "
97 *
98 */
99 final static EnumJvmMemoryGCCall JvmMemoryGCCallSupported
100 = new EnumJvmMemoryGCCall("supported");
101 final static EnumJvmMemoryGCCall JvmMemoryGCCallStart
102 = new EnumJvmMemoryGCCall("start");
103 final static EnumJvmMemoryGCCall JvmMemoryGCCallFailed
104 = new EnumJvmMemoryGCCall("failed");
105 final static EnumJvmMemoryGCCall JvmMemoryGCCallStarted
106 = new EnumJvmMemoryGCCall("started");
107
108 /**
109 * Variable for storing the value of "JvmMemoryGCVerboseLevel".
110 *
111 * "State of the -verbose:gc state.
112 *
113 * verbose: if the -verbose:gc flag is on,
114 * silent: otherwise.
115 *
116 * See java.management.MemoryMXBean.isVerbose(),
117 * java.management.MemoryMXBean.setVerbose()
118 * "
119 *
120 */
121 final static EnumJvmMemoryGCVerboseLevel JvmMemoryGCVerboseLevelVerbose =
122 new EnumJvmMemoryGCVerboseLevel("verbose");
123 final static EnumJvmMemoryGCVerboseLevel JvmMemoryGCVerboseLevelSilent =
124 new EnumJvmMemoryGCVerboseLevel("silent");
125
126 /**
127 * Constructor for the "JvmMemory" group.
128 * If the group contains a table, the entries created through an
129 * SNMP SET will not be registered in Java DMK.
130 */
131 public JvmMemoryImpl(SnmpMib myMib) {
132 }
133
134
135 /**
136 * Constructor for the "JvmMemory" group.
137 * If the group contains a table, the entries created through an
138 * SNMP SET will be AUTOMATICALLY REGISTERED in Java DMK.
139 */
140 public JvmMemoryImpl(SnmpMib myMib, MBeanServer server) {
141 // no entry will be registered since the table is virtual.
142 }
143
144 final static String heapMemoryTag = "jvmMemory.getHeapMemoryUsage";
145 final static String nonHeapMemoryTag = "jvmMemory.getNonHeapMemoryUsage";
146
147 private MemoryUsage getMemoryUsage(MemoryType type) {
148 if (type == MemoryType.HEAP) {
149 return ManagementFactory.getMemoryMXBean().getHeapMemoryUsage();
150 } else {
151 return ManagementFactory.getMemoryMXBean().getNonHeapMemoryUsage();
152 }
153 }
154
155 MemoryUsage getNonHeapMemoryUsage() {
156 try {
157 final Map<Object, Object> m = JvmContextFactory.getUserData();
158
159 if (m != null) {
160 final MemoryUsage cached = (MemoryUsage)
161 m.get(nonHeapMemoryTag);
162 if (cached != null) {
163 log.debug("getNonHeapMemoryUsage",
164 "jvmMemory.getNonHeapMemoryUsage found in cache.");
165 return cached;
166 }
167
168 final MemoryUsage u = getMemoryUsage(MemoryType.NON_HEAP);
169
170 // getNonHeapMemoryUsage() never returns null.
171 //
172 // if (u == null) u=MemoryUsage.INVALID;
173
174 m.put(nonHeapMemoryTag,u);
175 return u;
176 }
177 // Should never come here.
178 // Log error!
179 log.trace("getNonHeapMemoryUsage",
180 "ERROR: should never come here!");
181 return getMemoryUsage(MemoryType.NON_HEAP);
182 } catch (RuntimeException x) {
183 log.trace("getNonHeapMemoryUsage",
184 "Failed to get NonHeapMemoryUsage: " + x);
185 log.debug("getNonHeapMemoryUsage",x);
186 throw x;
187 }
188
189 }
190
191 MemoryUsage getHeapMemoryUsage() {
192 try {
193 final Map<Object, Object> m = JvmContextFactory.getUserData();
194
195 if (m != null) {
196 final MemoryUsage cached = (MemoryUsage)m.get(heapMemoryTag);
197 if (cached != null) {
198 log.debug("getHeapMemoryUsage",
199 "jvmMemory.getHeapMemoryUsage found in cache.");
200 return cached;
201 }
202
203 final MemoryUsage u = getMemoryUsage(MemoryType.HEAP);
204
205 // getHeapMemoryUsage() never returns null.
206 //
207 // if (u == null) u=MemoryUsage.INVALID;
208
209 m.put(heapMemoryTag,u);
210 return u;
211 }
212
213 // Should never come here.
214 // Log error!
215 log.trace("getHeapMemoryUsage", "ERROR: should never come here!");
216 return getMemoryUsage(MemoryType.HEAP);
217 } catch (RuntimeException x) {
218 log.trace("getHeapMemoryUsage",
219 "Failed to get HeapMemoryUsage: " + x);
220 log.debug("getHeapMemoryUsage",x);
221 throw x;
222 }
223 }
224
225 static final Long Long0 = new Long(0);
226
227 /**
228 * Getter for the "JvmMemoryNonHeapMaxSize" variable.
229 */
230 public Long getJvmMemoryNonHeapMaxSize()
231 throws SnmpStatusException {
232 final long val = getNonHeapMemoryUsage().getMax();
233 if (val > -1) return new Long(val);
234 else return Long0;
235 }
236
237 /**
238 * Getter for the "JvmMemoryNonHeapCommitted" variable.
239 */
240 public Long getJvmMemoryNonHeapCommitted() throws SnmpStatusException {
241 final long val = getNonHeapMemoryUsage().getCommitted();
242 if (val > -1) return new Long(val);
243 else return Long0;
244 }
245
246 /**
247 * Getter for the "JvmMemoryNonHeapUsed" variable.
248 */
249 public Long getJvmMemoryNonHeapUsed() throws SnmpStatusException {
250 final long val = getNonHeapMemoryUsage().getUsed();
251 if (val > -1) return new Long(val);
252 else return Long0;
253 }
254
255 /**
256 * Getter for the "JvmMemoryNonHeapInitSize" variable.
257 */
258 public Long getJvmMemoryNonHeapInitSize() throws SnmpStatusException {
259 final long val = getNonHeapMemoryUsage().getInit();
260 if (val > -1) return new Long(val);
261 else return Long0;
262 }
263
264 /**
265 * Getter for the "JvmMemoryHeapMaxSize" variable.
266 */
267 public Long getJvmMemoryHeapMaxSize() throws SnmpStatusException {
268 final long val = getHeapMemoryUsage().getMax();
269 if (val > -1) return new Long(val);
270 else return Long0;
271 }
272
273 /**
274 * Getter for the "JvmMemoryGCCall" variable.
275 */
276 public EnumJvmMemoryGCCall getJvmMemoryGCCall()
277 throws SnmpStatusException {
278 final Map m = JvmContextFactory.getUserData();
279
280 if (m != null) {
281 final EnumJvmMemoryGCCall cached
282 = (EnumJvmMemoryGCCall) m.get("jvmMemory.getJvmMemoryGCCall");
283 if (cached != null) return cached;
284 }
285 return JvmMemoryGCCallSupported;
286 }
287
288 /**
289 * Setter for the "JvmMemoryGCCall" variable.
290 */
291 public void setJvmMemoryGCCall(EnumJvmMemoryGCCall x)
292 throws SnmpStatusException {
293 if (x.intValue() == JvmMemoryGCCallStart.intValue()) {
294 final Map<Object, Object> m = JvmContextFactory.getUserData();
295
296 try {
297 ManagementFactory.getMemoryMXBean().gc();
298 if (m != null) m.put("jvmMemory.getJvmMemoryGCCall",
299 JvmMemoryGCCallStarted);
300 } catch (Exception ex) {
301 if (m != null) m.put("jvmMemory.getJvmMemoryGCCall",
302 JvmMemoryGCCallFailed);
303 }
304 return;
305 }
306 throw new SnmpStatusException(SnmpDefinitions.snmpRspWrongValue);
307 }
308
309 /**
310 * Checker for the "JvmMemoryGCCall" variable.
311 */
312 public void checkJvmMemoryGCCall(EnumJvmMemoryGCCall x)
313 throws SnmpStatusException {
314 if (x.intValue() != JvmMemoryGCCallStart.intValue())
315 throw new SnmpStatusException(SnmpDefinitions.snmpRspWrongValue);
316 }
317
318 /**
319 * Getter for the "JvmMemoryHeapCommitted" variable.
320 */
321 public Long getJvmMemoryHeapCommitted() throws SnmpStatusException {
322 final long val = getHeapMemoryUsage().getCommitted();
323 if (val > -1) return new Long(val);
324 else return Long0;
325 }
326
327 /**
328 * Getter for the "JvmMemoryGCVerboseLevel" variable.
329 */
330 public EnumJvmMemoryGCVerboseLevel getJvmMemoryGCVerboseLevel()
331 throws SnmpStatusException {
332 if (ManagementFactory.getMemoryMXBean().isVerbose())
333 return JvmMemoryGCVerboseLevelVerbose;
334 else
335 return JvmMemoryGCVerboseLevelSilent;
336 }
337
338 /**
339 * Setter for the "JvmMemoryGCVerboseLevel" variable.
340 */
341 public void setJvmMemoryGCVerboseLevel(EnumJvmMemoryGCVerboseLevel x)
342 throws SnmpStatusException {
343 if (JvmMemoryGCVerboseLevelVerbose.intValue() == x.intValue())
344 ManagementFactory.getMemoryMXBean().setVerbose(true);
345 else
346 ManagementFactory.getMemoryMXBean().setVerbose(false);
347 }
348
349 /**
350 * Checker for the "JvmMemoryGCVerboseLevel" variable.
351 */
352 public void checkJvmMemoryGCVerboseLevel(EnumJvmMemoryGCVerboseLevel x)
353 throws SnmpStatusException {
354 // Nothing to check...
355 }
356
357 /**
358 * Getter for the "JvmMemoryHeapUsed" variable.
359 */
360 public Long getJvmMemoryHeapUsed() throws SnmpStatusException {
361 final long val = getHeapMemoryUsage().getUsed();
362 if (val > -1) return new Long(val);
363 else return Long0;
364 }
365
366 /**
367 * Getter for the "JvmMemoryHeapInitSize" variable.
368 */
369 public Long getJvmMemoryHeapInitSize() throws SnmpStatusException {
370 final long val = getHeapMemoryUsage().getInit();
371 if (val > -1) return new Long(val);
372 else return Long0;
373 }
374
375 /**
376 * Getter for the "JvmMemoryPendingFinalCount" variable.
377 */
378 public Long getJvmMemoryPendingFinalCount()
379 throws SnmpStatusException {
380 final long val = ManagementFactory.getMemoryMXBean().
381 getObjectPendingFinalizationCount();
382
383 if (val > -1) return new Long((int)val);
384
385 // Should never happen... but stay safe all the same.
386 //
387 else return new Long(0);
388 }
389
390 static final MibLogger log = new MibLogger(JvmMemoryImpl.class);
391}