1 /* 2 * Copyright (c) 2003, 2012, 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 // jmx imports 28 // 29 import javax.management.MBeanServer; 30 import com.sun.jmx.snmp.SnmpStatusException; 31 import com.sun.jmx.snmp.SnmpDefinitions; 32 33 // jdmk imports 34 // 35 import com.sun.jmx.snmp.agent.SnmpMib; 36 37 import java.util.Map; 38 import java.lang.management.ManagementFactory; 39 import java.lang.management.MemoryUsage; 40 import java.lang.management.MemoryType; 41 import java.lang.management.MemoryMXBean; 42 import javax.management.openmbean.CompositeData; 43 44 import sun.management.snmp.jvmmib.JvmMemoryMBean; 45 import sun.management.snmp.jvmmib.EnumJvmMemoryGCCall; 46 import sun.management.snmp.jvmmib.EnumJvmMemoryGCVerboseLevel; 47 import sun.management.snmp.util.MibLogger; 48 import sun.management.snmp.util.JvmContextFactory; 49 50 /** 51 * The class is used for implementing the "JvmMemory" group. 52 */ 53 public 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 = 0L; 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 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 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 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 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 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<Object,Object> 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 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 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 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 val; 384 385 // Should never happen... but stay safe all the same. 386 // 387 else return 0L; 388 } 389 390 static final MibLogger log = new MibLogger(JvmMemoryImpl.class); 391 }