/* * Copyright to the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.rioproject.impl.system.measurable.memory.pool; import com.sun.jini.config.Config; import net.jini.config.Configuration; import net.jini.config.ConfigurationException; import org.rioproject.impl.system.measurable.MeasurableCapability; import org.rioproject.impl.system.measurable.MeasurableMonitor; import org.rioproject.system.MeasuredResource; import org.rioproject.system.measurable.memory.pool.CalculableMemoryPool; import org.rioproject.system.measurable.memory.pool.MemoryPoolUtilization; import org.rioproject.watch.ThresholdValues; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.lang.management.ManagementFactory; import java.lang.management.MemoryPoolMXBean; /** * The MemoryPool is used to monitor a JMX memory pool. */ /* Suppress PMD warnings for the invocation of createMeasurableMonitor() during object * construction. This is by design. */ @SuppressWarnings("PMD.ConstructorCallsOverridableMethod") public class MemoryPool extends MeasurableCapability { /** Iteration value for calculating utilization of sampleSize >1 */ private int count; /** Temporary utilization value */ private double tempUtilization; /** Computed utilization value */ private double utilization; private MeasurableMonitor<MemoryPoolUtilization> monitor; /** Component for Configuration and Logging */ private static final String COMPONENT = "org.rioproject.system.memory.pool"; private static final String VIEW = "org.rioproject.system.memory.CalculableMemoryPoolView"; static Logger logger = LoggerFactory.getLogger(COMPONENT); /** * Construct a MemoryPool object * * @param id Identifier to use * @param config Configuration object * @param thresholdValues ThresholdValues to use */ public MemoryPool(String id, Configuration config, ThresholdValues thresholdValues) { super(id, COMPONENT, config); setThresholdValues(thresholdValues); monitor = createMeasurableMonitor(id); setView(VIEW); if(monitor==null) { setEnabled(false); StringBuilder poolNames = new StringBuilder(); for(MemoryPoolMXBean mBean : ManagementFactory.getMemoryPoolMXBeans()) { if(poolNames.length()>0) poolNames.append(", "); poolNames.append(mBean.getName()); } logger.warn("Unable to obtain a monitor for {}, available memory pools are [{}]. " + "Cannot monitor the requested memory pool", id, poolNames); } try { sampleSize = Config.getIntEntry(config, COMPONENT, "sampleSize", 1, /* default */ 1, /* min */ 10); /* max */ setSampleSize(sampleSize); } catch (ConfigurationException e) { logger.warn("Unable to obtain {}.sampleSize from configuration, use default and continue", COMPONENT); } try { long reportRate = Config.getLongEntry(config, COMPONENT, "reportRate", DEFAULT_PERIOD, /* default */ 5000, /* min */ Integer.MAX_VALUE); /* max */ setPeriod(reportRate); } catch (ConfigurationException e) { logger.warn("Unable to obtain {}.reportRate from configuration, use default and continue", COMPONENT); } } public double getUtilization() { return utilization; } /** * Override PeriodicWatch.start() to get an initial reading prior to * scheduling */ @Override public void start() { checkValue(); super.start(); } public void checkValue() { MemoryPoolUtilization mRes = monitor.getMeasuredResource(); double utilization = calculateUtilization(mRes); long now = System.currentTimeMillis(); addWatchRecord(new CalculableMemoryPool(getId(), utilization, now, mRes)); setLastMeasuredResource(mRes); } protected MeasurableMonitor<MemoryPoolUtilization> createMeasurableMonitor(String id) { MemoryPoolMXBeanMonitor m = new MemoryPoolMXBeanMonitor(); m.setID(id); m.setThresholdValues(getThresholdValues()); MemoryPoolMXBean memoryBean = m.getMemoryPoolMXBean(); if(memoryBean==null) m = null; return m; } double calculateUtilization(MeasuredResource mRes) { count++; tempUtilization += mRes.getValue(); if(count==sampleSize) { utilization = tempUtilization/sampleSize; count = 0; tempUtilization = 0; } logger.trace("Memory : utilization={}", utilization); return utilization; } }