/** * Memory * Copyright 14.01.2017 by Michael Peter Christen, @0rb1t3r * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program in the file lgpl21.txt * If not, see <http://www.gnu.org/licenses/>. */ package net.yacy.grid.tools; import java.lang.management.ManagementFactory; import java.lang.management.OperatingSystemMXBean; import java.lang.management.ThreadInfo; import java.lang.management.ThreadMXBean; import net.yacy.grid.mcp.Data; public class Memory { private static final Runtime runtime = Runtime.getRuntime(); public final static OperatingSystemMXBean osBean = ManagementFactory.getOperatingSystemMXBean(); public final static ThreadMXBean threadBean = ManagementFactory.getThreadMXBean(); public final static float shortmemthreshold = 0.9f; /** * memory that is free without increasing of total memory taken from os * @return bytes */ public static final long free() { return runtime.freeMemory(); } /** * memory that is available including increasing total memory up to maximum * @return bytes */ public static final long available() { return assigned() - total() + free(); } /** * maximum memory the Java virtual will allocate machine; may vary over time in some cases * @return bytes */ public static final long assigned() { return runtime.maxMemory(); // can be Long.MAX_VALUE if unlimited } /** * currently allocated memory in the Java virtual machine; may vary over time * @return bytes */ public static final long total() { return runtime.totalMemory(); } /** * memory that is currently bound in objects * @return used bytes */ public static final long used() { return total() - free(); } /** * get number of CPU cores * @return number of CPU cores */ public static final long cores() { return runtime.availableProcessors(); } /** * get the system load within the last minute * @return the system load or a negative number if the load is not available */ public static double load() { return osBean.getSystemLoadAverage(); } /** * find out the number of thread deadlocks. WARNING: this is a time-consuming task * @return the number of deadlocked threads */ public static long deadlocks() { long[] deadlockIDs = threadBean.findDeadlockedThreads(); if (deadlockIDs == null) return 0; return deadlockIDs.length; } /** * write deadlocked threads as to the log as warning */ public static void logDeadlocks() { long[] deadlockIDs = ManagementFactory.getThreadMXBean().findDeadlockedThreads(); if (deadlockIDs == null) return; ThreadInfo[] infos = ManagementFactory.getThreadMXBean().getThreadInfo(deadlockIDs, true, true); for (ThreadInfo ti : infos) { Data.logger.warn("DEADLOCKREPORT: " + ti.toString()); } } private static long lastGCtime = 0; /** * run garbage collection * @return true if gc was actually triggered, false if no gc was done because time to latest gc was too short */ public final synchronized static boolean lazyGC() { long now = System.currentTimeMillis(); if (now - lastGCtime > 10000) { System.gc(); lastGCtime = now; return true; } return false; } /** * @return if last request failed */ public static boolean shortStatus() { lazyGC(); return used() >= assigned() * shortmemthreshold ; } }