patterntesting.runtime.monitor.MemoryGuard Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of patterntesting-rt Show documentation
Show all versions of patterntesting-rt Show documentation
PatternTesting Runtime (patterntesting-rt) is the runtime component for
the PatternTesting framework. It provides the annotations and base classes
for the PatternTesting testing framework (e.g. patterntesting-check,
patterntesting-concurrent or patterntesting-exception) but can be also
used standalone for classpath monitoring or profiling.
It uses AOP and AspectJ to perform this feat.
/*
* $Id: MemoryGuard.java,v 1.8 2011/07/09 21:43:22 oboehm Exp $
*
* Copyright (c) 2008 by Oliver Boehm
*
* 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 orimplied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* (c)reated 19.01.2009 by oliver ([email protected])
*/
package patterntesting.runtime.monitor;
import org.slf4j.*;
import patterntesting.runtime.util.Converter;
/**
* The Class MemoryGuard.
*
* @author oliver
* @since 19.01.2009
* @version $Revision: 1.8 $
*/
public final class MemoryGuard {
private static final Logger log = LoggerFactory.getLogger(MemoryGuard.class);
private static final long maxMem = Runtime.getRuntime().maxMemory();
private static BackgroundLogger backgroundTask;
/** No need to instantiate it (utility class). */
private MemoryGuard() {}
/**
* Gets the free memory.
*
* @return the free memory
*/
public static long getFreeMemory() {
Runtime runtime = Runtime.getRuntime();
long totalMem = runtime.totalMemory();
return runtime.freeMemory() + (maxMem - totalMem);
}
/**
* Gets the free memory in percent.
*
* @return the free memory in percent
*/
public static int getFreeMemoryInPercent() {
long freeMem = getFreeMemory();
int rate = (int) ((freeMem + 50) * 100 / maxMem);
return rate;
}
/**
* Gets the free memory as string.
*
* @return the free memory as string
*/
public static String getFreeMemoryAsString() {
return Converter.getMemoryAsString(getFreeMemory());
}
/**
* Log memory.
*
* @see #logMemory(Logger)
*/
public static void logMemory() {
logMemory(log);
}
/**
* Logs a message if free memory falls down below x% of maximal heap size
* where x is:
*
* - x < 1%: logs a fatal message
* - 1% <= x < 2%: logs an error
* - 1% <= x < 10%: logs a warning
* - 10% <= x < 20%: logs an info message
* - 20% <= x < 50%: logs debug message
* - x >= 50%: tracing
*
.
*
* @param lg the log
*/
public static void logMemory(final Logger lg) {
int freeMemRate = getFreeMemoryInPercent();
if (freeMemRate < 10) {
System.gc();
if (lg.isTraceEnabled()) {
lg.trace("gc() called because free memory is below 10% ("
+ freeMemRate + "%)");
}
freeMemRate = getFreeMemoryInPercent();
}
if (freeMemRate < 2) {
if (lg.isErrorEnabled()) {
lg.error(getMemoryLogMessage(freeMemRate));
}
} else if (freeMemRate < 10) {
if (lg.isWarnEnabled()) {
lg.warn(getMemoryLogMessage(freeMemRate));
}
} else if (freeMemRate < 20) {
if (lg.isInfoEnabled()) {
lg.info(getMemoryLogMessage(freeMemRate));
}
} else if (freeMemRate < 50) {
if (lg.isDebugEnabled()) {
lg.debug(getMemoryLogMessage(freeMemRate));
}
} else {
if (lg.isTraceEnabled()) {
lg.trace(getMemoryLogMessage(freeMemRate));
}
}
}
/**
* Gets the memory log message.
*
* @return the memory log message
*/
public static String getMemoryLogMessage() {
int freeMemRate = getFreeMemoryInPercent();
return getMemoryLogMessage(freeMemRate);
}
private static String getMemoryLogMessage(final int freeMemRate) {
return freeMemRate + "% of memory is free (" + getFreeMemoryAsString()
+ ")";
}
/**
* Every x milliseconds the free memory is checked and printed into the log
* (according the log level). This is done with in a separated background
* thread. If there is already a background thread running it will be
* suspended before a new background thread will be started.
*
* @param interval (the sleep intervall in milliseconds, e.g. 300000 for 5 min.)
*
* @throws InterruptedException the interrupted exception
*/
public static synchronized void logFreeMemory(final long interval)
throws InterruptedException {
if (log.isTraceEnabled()) {
if (backgroundTask == null) {
backgroundTask = new BackgroundLogger(interval);
log.trace("starting " + backgroundTask + "...");
Thread backgroundThread = new Thread(backgroundTask, "background");
backgroundThread.setDaemon(true);
backgroundThread.setPriority(Thread.MIN_PRIORITY);
backgroundThread.start();
} else {
backgroundTask.setInterval(interval);
log.trace(backgroundTask + " changed");
}
}
}
/**
* This inner class do the job for us. It polls the memory size and logs
* it.
*
* @author oliver
* @since 01.07.2009
*/
static class BackgroundLogger implements Runnable {
private long interval;
/**
* Instantiates a new background logger.
*
* @param interval the interval
*/
public BackgroundLogger(final long interval) {
this.interval = interval;
}
/**
* Sets the interval.
*
* @param interval the new interval
*/
public void setInterval(final long interval) {
this.interval = interval;
}
/**
* @see java.lang.Runnable#run()
*/
public void run() {
while (true) {
logMemory();
try {
Thread.sleep(interval);
} catch (InterruptedException e) {
log.debug(this + " interrupted", e);
break;
}
}
}
/**
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return this.getClass().getSimpleName() + "(" + interval + "ms)";
}
}
}
/**
* $Log: MemoryGuard.java,v $
* Revision 1.8 2011/07/09 21:43:22 oboehm
* switched from commons-logging to SLF4J
*
* Revision 1.7 2010/07/22 16:50:45 oboehm
* checkstyle fixing and tuning
*
* Revision 1.6 2010/07/05 20:26:55 oboehm
* background logger is only started in TRACE level
*
* Revision 1.5 2010/06/08 21:32:53 oboehm
* nearly half of the checkstyle warnings fixed
*
* Revision 1.4 2010/04/22 18:32:01 oboehm
* compiler warnings fixed
*
* Revision 1.3 2010/04/22 18:27:19 oboehm
* code cleanup of src/main/java
*
* Revision 1.2 2010/01/06 15:57:16 oboehm
* some FindBug warnings removed
* warning level increased
*
* Revision 1.1 2010/01/05 13:26:17 oboehm
* begin with 1.0
*
* Revision 1.13 2009/12/28 10:07:23 oboehm
* missing Javadocs completed
*
* Revision 1.12 2009/12/19 22:34:09 oboehm
* trailing spaces removed
*
* Revision 1.11 2009/12/14 17:14:31 oboehm
* trailing tabs removed
*
* Revision 1.10 2009/09/25 14:49:43 oboehm
* javadocs completed with the help of JAutodoc
*
* Revision 1.9 2009/07/04 10:54:03 oboehm
* logFreeMemory can now be called more than once
*
* Revision 1.8 2009/03/24 08:51:44 oboehm
* compiler warning fixed
*
* Revision 1.7 2009/03/24 08:51:05 oboehm
* RunBackgroundAspect no longer available - manual implemented
*
* $Source: /cvsroot/patterntesting/PatternTesting10/patterntesting-rt/src/main/java/patterntesting/runtime/monitor/MemoryGuard.java,v $
*/