| /* |
| * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved. |
| * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
| * |
| * This code is free software; you can redistribute it and/or modify it |
| * under the terms of the GNU General Public License version 2 only, as |
| * published by the Free Software Foundation. Oracle designates this |
| * particular file as subject to the "Classpath" exception as provided |
| * by Oracle in the LICENSE file that accompanied this code. |
| * |
| * This code is distributed in the hope that it will be useful, but WITHOUT |
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
| * version 2 for more details (a copy is included in the LICENSE file that |
| * accompanied this code). |
| * |
| * You should have received a copy of the GNU General Public License version |
| * 2 along with this work; if not, write to the Free Software Foundation, |
| * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
| * |
| * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
| * or visit www.oracle.com if you need additional information or have any |
| * questions. |
| */ |
| package sun.management.snmp.jvminstr; |
| |
| // jmx imports |
| // |
| import javax.management.MBeanServer; |
| import com.sun.jmx.snmp.SnmpStatusException; |
| import com.sun.jmx.snmp.SnmpDefinitions; |
| |
| // jdmk imports |
| // |
| import com.sun.jmx.snmp.agent.SnmpMib; |
| |
| import java.util.Map; |
| import java.lang.management.ManagementFactory; |
| import java.lang.management.MemoryUsage; |
| import java.lang.management.MemoryType; |
| import java.lang.management.MemoryMXBean; |
| import javax.management.openmbean.CompositeData; |
| |
| import sun.management.snmp.jvmmib.JvmMemoryMBean; |
| import sun.management.snmp.jvmmib.EnumJvmMemoryGCCall; |
| import sun.management.snmp.jvmmib.EnumJvmMemoryGCVerboseLevel; |
| import sun.management.snmp.util.MibLogger; |
| import sun.management.snmp.util.JvmContextFactory; |
| |
| /** |
| * The class is used for implementing the "JvmMemory" group. |
| */ |
| public class JvmMemoryImpl implements JvmMemoryMBean { |
| |
| /** |
| * Variable for storing the value of "JvmMemoryGCCall". |
| * |
| * "This object makes it possible to remotelly trigger the |
| * Garbage Collector in the JVM. |
| * |
| * This object's syntax is an enumeration which defines: |
| * |
| * * Two state values, that can be returned from a GET request: |
| * |
| * unsupported(1): means that remote invocation of gc() is not |
| * supported by the SNMP agent. |
| * supported(2) : means that remote invocation of gc() is supported |
| * by the SNMP agent. |
| * |
| * * One action value, that can be provided in a SET request to |
| * trigger the garbage collector: |
| * |
| * start(3) : means that a manager wishes to trigger |
| * garbage collection. |
| * |
| * * Two result value, that will be returned as a result of a |
| * SET request when remote invocation of gc is supported |
| * by the SNMP agent: |
| * |
| * started(4) : means that garbage collection was |
| * successfully triggered. It does not mean |
| * however that the action was successfullly |
| * completed: gc might still be running when |
| * this value is returned. |
| * failed(5) : means that garbage collection couldn't be |
| * triggered. |
| * |
| * * If remote invocation is not supported by the SNMP agent, then |
| * unsupported(1) will always be returned as a result of either |
| * a GET request, or a SET request with start(3) as input value. |
| * |
| * * If a SET request with anything but start(3) is received, then |
| * the agent will return a wrongValue error. |
| * |
| * See java.management.MemoryMXBean.gc() |
| * " |
| * |
| */ |
| final static EnumJvmMemoryGCCall JvmMemoryGCCallSupported |
| = new EnumJvmMemoryGCCall("supported"); |
| final static EnumJvmMemoryGCCall JvmMemoryGCCallStart |
| = new EnumJvmMemoryGCCall("start"); |
| final static EnumJvmMemoryGCCall JvmMemoryGCCallFailed |
| = new EnumJvmMemoryGCCall("failed"); |
| final static EnumJvmMemoryGCCall JvmMemoryGCCallStarted |
| = new EnumJvmMemoryGCCall("started"); |
| |
| /** |
| * Variable for storing the value of "JvmMemoryGCVerboseLevel". |
| * |
| * "State of the -verbose:gc state. |
| * |
| * verbose: if the -verbose:gc flag is on, |
| * silent: otherwise. |
| * |
| * See java.management.MemoryMXBean.isVerbose(), |
| * java.management.MemoryMXBean.setVerbose() |
| * " |
| * |
| */ |
| final static EnumJvmMemoryGCVerboseLevel JvmMemoryGCVerboseLevelVerbose = |
| new EnumJvmMemoryGCVerboseLevel("verbose"); |
| final static EnumJvmMemoryGCVerboseLevel JvmMemoryGCVerboseLevelSilent = |
| new EnumJvmMemoryGCVerboseLevel("silent"); |
| |
| /** |
| * Constructor for the "JvmMemory" group. |
| * If the group contains a table, the entries created through an |
| * SNMP SET will not be registered in Java DMK. |
| */ |
| public JvmMemoryImpl(SnmpMib myMib) { |
| } |
| |
| |
| /** |
| * Constructor for the "JvmMemory" group. |
| * If the group contains a table, the entries created through an |
| * SNMP SET will be AUTOMATICALLY REGISTERED in Java DMK. |
| */ |
| public JvmMemoryImpl(SnmpMib myMib, MBeanServer server) { |
| // no entry will be registered since the table is virtual. |
| } |
| |
| final static String heapMemoryTag = "jvmMemory.getHeapMemoryUsage"; |
| final static String nonHeapMemoryTag = "jvmMemory.getNonHeapMemoryUsage"; |
| |
| private MemoryUsage getMemoryUsage(MemoryType type) { |
| if (type == MemoryType.HEAP) { |
| return ManagementFactory.getMemoryMXBean().getHeapMemoryUsage(); |
| } else { |
| return ManagementFactory.getMemoryMXBean().getNonHeapMemoryUsage(); |
| } |
| } |
| |
| MemoryUsage getNonHeapMemoryUsage() { |
| try { |
| final Map<Object, Object> m = JvmContextFactory.getUserData(); |
| |
| if (m != null) { |
| final MemoryUsage cached = (MemoryUsage) |
| m.get(nonHeapMemoryTag); |
| if (cached != null) { |
| log.debug("getNonHeapMemoryUsage", |
| "jvmMemory.getNonHeapMemoryUsage found in cache."); |
| return cached; |
| } |
| |
| final MemoryUsage u = getMemoryUsage(MemoryType.NON_HEAP); |
| |
| // getNonHeapMemoryUsage() never returns null. |
| // |
| // if (u == null) u=MemoryUsage.INVALID; |
| |
| m.put(nonHeapMemoryTag,u); |
| return u; |
| } |
| // Should never come here. |
| // Log error! |
| log.trace("getNonHeapMemoryUsage", |
| "ERROR: should never come here!"); |
| return getMemoryUsage(MemoryType.NON_HEAP); |
| } catch (RuntimeException x) { |
| log.trace("getNonHeapMemoryUsage", |
| "Failed to get NonHeapMemoryUsage: " + x); |
| log.debug("getNonHeapMemoryUsage",x); |
| throw x; |
| } |
| |
| } |
| |
| MemoryUsage getHeapMemoryUsage() { |
| try { |
| final Map<Object, Object> m = JvmContextFactory.getUserData(); |
| |
| if (m != null) { |
| final MemoryUsage cached = (MemoryUsage)m.get(heapMemoryTag); |
| if (cached != null) { |
| log.debug("getHeapMemoryUsage", |
| "jvmMemory.getHeapMemoryUsage found in cache."); |
| return cached; |
| } |
| |
| final MemoryUsage u = getMemoryUsage(MemoryType.HEAP); |
| |
| // getHeapMemoryUsage() never returns null. |
| // |
| // if (u == null) u=MemoryUsage.INVALID; |
| |
| m.put(heapMemoryTag,u); |
| return u; |
| } |
| |
| // Should never come here. |
| // Log error! |
| log.trace("getHeapMemoryUsage", "ERROR: should never come here!"); |
| return getMemoryUsage(MemoryType.HEAP); |
| } catch (RuntimeException x) { |
| log.trace("getHeapMemoryUsage", |
| "Failed to get HeapMemoryUsage: " + x); |
| log.debug("getHeapMemoryUsage",x); |
| throw x; |
| } |
| } |
| |
| static final Long Long0 = new Long(0); |
| |
| /** |
| * Getter for the "JvmMemoryNonHeapMaxSize" variable. |
| */ |
| public Long getJvmMemoryNonHeapMaxSize() |
| throws SnmpStatusException { |
| final long val = getNonHeapMemoryUsage().getMax(); |
| if (val > -1) return new Long(val); |
| else return Long0; |
| } |
| |
| /** |
| * Getter for the "JvmMemoryNonHeapCommitted" variable. |
| */ |
| public Long getJvmMemoryNonHeapCommitted() throws SnmpStatusException { |
| final long val = getNonHeapMemoryUsage().getCommitted(); |
| if (val > -1) return new Long(val); |
| else return Long0; |
| } |
| |
| /** |
| * Getter for the "JvmMemoryNonHeapUsed" variable. |
| */ |
| public Long getJvmMemoryNonHeapUsed() throws SnmpStatusException { |
| final long val = getNonHeapMemoryUsage().getUsed(); |
| if (val > -1) return new Long(val); |
| else return Long0; |
| } |
| |
| /** |
| * Getter for the "JvmMemoryNonHeapInitSize" variable. |
| */ |
| public Long getJvmMemoryNonHeapInitSize() throws SnmpStatusException { |
| final long val = getNonHeapMemoryUsage().getInit(); |
| if (val > -1) return new Long(val); |
| else return Long0; |
| } |
| |
| /** |
| * Getter for the "JvmMemoryHeapMaxSize" variable. |
| */ |
| public Long getJvmMemoryHeapMaxSize() throws SnmpStatusException { |
| final long val = getHeapMemoryUsage().getMax(); |
| if (val > -1) return new Long(val); |
| else return Long0; |
| } |
| |
| /** |
| * Getter for the "JvmMemoryGCCall" variable. |
| */ |
| public EnumJvmMemoryGCCall getJvmMemoryGCCall() |
| throws SnmpStatusException { |
| final Map m = JvmContextFactory.getUserData(); |
| |
| if (m != null) { |
| final EnumJvmMemoryGCCall cached |
| = (EnumJvmMemoryGCCall) m.get("jvmMemory.getJvmMemoryGCCall"); |
| if (cached != null) return cached; |
| } |
| return JvmMemoryGCCallSupported; |
| } |
| |
| /** |
| * Setter for the "JvmMemoryGCCall" variable. |
| */ |
| public void setJvmMemoryGCCall(EnumJvmMemoryGCCall x) |
| throws SnmpStatusException { |
| if (x.intValue() == JvmMemoryGCCallStart.intValue()) { |
| final Map<Object, Object> m = JvmContextFactory.getUserData(); |
| |
| try { |
| ManagementFactory.getMemoryMXBean().gc(); |
| if (m != null) m.put("jvmMemory.getJvmMemoryGCCall", |
| JvmMemoryGCCallStarted); |
| } catch (Exception ex) { |
| if (m != null) m.put("jvmMemory.getJvmMemoryGCCall", |
| JvmMemoryGCCallFailed); |
| } |
| return; |
| } |
| throw new SnmpStatusException(SnmpDefinitions.snmpRspWrongValue); |
| } |
| |
| /** |
| * Checker for the "JvmMemoryGCCall" variable. |
| */ |
| public void checkJvmMemoryGCCall(EnumJvmMemoryGCCall x) |
| throws SnmpStatusException { |
| if (x.intValue() != JvmMemoryGCCallStart.intValue()) |
| throw new SnmpStatusException(SnmpDefinitions.snmpRspWrongValue); |
| } |
| |
| /** |
| * Getter for the "JvmMemoryHeapCommitted" variable. |
| */ |
| public Long getJvmMemoryHeapCommitted() throws SnmpStatusException { |
| final long val = getHeapMemoryUsage().getCommitted(); |
| if (val > -1) return new Long(val); |
| else return Long0; |
| } |
| |
| /** |
| * Getter for the "JvmMemoryGCVerboseLevel" variable. |
| */ |
| public EnumJvmMemoryGCVerboseLevel getJvmMemoryGCVerboseLevel() |
| throws SnmpStatusException { |
| if (ManagementFactory.getMemoryMXBean().isVerbose()) |
| return JvmMemoryGCVerboseLevelVerbose; |
| else |
| return JvmMemoryGCVerboseLevelSilent; |
| } |
| |
| /** |
| * Setter for the "JvmMemoryGCVerboseLevel" variable. |
| */ |
| public void setJvmMemoryGCVerboseLevel(EnumJvmMemoryGCVerboseLevel x) |
| throws SnmpStatusException { |
| if (JvmMemoryGCVerboseLevelVerbose.intValue() == x.intValue()) |
| ManagementFactory.getMemoryMXBean().setVerbose(true); |
| else |
| ManagementFactory.getMemoryMXBean().setVerbose(false); |
| } |
| |
| /** |
| * Checker for the "JvmMemoryGCVerboseLevel" variable. |
| */ |
| public void checkJvmMemoryGCVerboseLevel(EnumJvmMemoryGCVerboseLevel x) |
| throws SnmpStatusException { |
| // Nothing to check... |
| } |
| |
| /** |
| * Getter for the "JvmMemoryHeapUsed" variable. |
| */ |
| public Long getJvmMemoryHeapUsed() throws SnmpStatusException { |
| final long val = getHeapMemoryUsage().getUsed(); |
| if (val > -1) return new Long(val); |
| else return Long0; |
| } |
| |
| /** |
| * Getter for the "JvmMemoryHeapInitSize" variable. |
| */ |
| public Long getJvmMemoryHeapInitSize() throws SnmpStatusException { |
| final long val = getHeapMemoryUsage().getInit(); |
| if (val > -1) return new Long(val); |
| else return Long0; |
| } |
| |
| /** |
| * Getter for the "JvmMemoryPendingFinalCount" variable. |
| */ |
| public Long getJvmMemoryPendingFinalCount() |
| throws SnmpStatusException { |
| final long val = ManagementFactory.getMemoryMXBean(). |
| getObjectPendingFinalizationCount(); |
| |
| if (val > -1) return new Long((int)val); |
| |
| // Should never happen... but stay safe all the same. |
| // |
| else return new Long(0); |
| } |
| |
| static final MibLogger log = new MibLogger(JvmMemoryImpl.class); |
| } |