patterntesting.runtime.monitor.MemoryGuard Maven / Gradle / Ivy
/*
* $Id: MemoryGuard.java,v 1.11 2016/03/05 17:45:59 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
* @version $Revision: 1.11 $
* @since 19.01.2009
*/
public final class MemoryGuard {
private static final Logger LOG = LoggerFactory.getLogger(MemoryGuard.class);
private static final long MAX_MEM = 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() + (MAX_MEM - 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 / MAX_MEM);
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;
}
/**
* Run.
*
* @see java.lang.Runnable#run()
*/
public void run() {
while (true) {
logMemory();
try {
Thread.sleep(interval);
} catch (InterruptedException e) {
LOG.debug(this + " interrupted:", e);
Thread.currentThread().interrupt();
break;
}
}
}
/**
* To string.
*
* @return the string
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return this.getClass().getSimpleName() + "(" + interval + "ms)";
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy