All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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