Java tutorial
/* * @(#)$Id: SystemUtils.java 3870 2008-05-21 02:46:25Z yui $ * * Copyright 2006-2008 Makoto YUI * * 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. * * Contributors: * Makoto YUI - initial implementation */ package xbird.util.system; import java.lang.management.GarbageCollectorMXBean; import java.lang.management.ManagementFactory; import java.lang.management.MemoryMXBean; import java.lang.management.MemoryUsage; import java.lang.management.OperatingSystemMXBean; import java.lang.management.RuntimeMXBean; import java.lang.reflect.Method; import java.security.AccessController; import java.util.List; import org.apache.commons.logging.LogFactory; import xbird.config.Settings; /** * * <DIV lang="en"></DIV> * <DIV lang="ja"></DIV> * * @author Makoto YUI (yuin405+xbird@gmail.com) */ public final class SystemUtils { public static final String OS_NAME = System.getProperty("os.name"); public static final String JAVA_VERSION = System.getProperty("java.version"); public static final boolean IS_OS_SUN_OS = OS_NAME.startsWith("SunOS") || OS_NAME.startsWith("Solaris"); public static final boolean IS_OS_LINUX = OS_NAME.startsWith("Linux") || OS_NAME.startsWith("LINUX"); public static final boolean IS_OS_WINDOWS = OS_NAME.startsWith("Windows"); public static final float JAVA_VERSION_FLOAT = parseJavaVersion(getJavaVersion(JAVA_VERSION)); private static final int NPROCS = Runtime.getRuntime().availableProcessors(); public static final boolean IS_SUN_VM = System.getProperty("java.vm.vendor").indexOf("Sun") != -1; private static final boolean preferSigar; private static Object sigarInstance = null; private static Method sigarCpuPercMtd = null; private static Method sigarCpuCombinedMtd = null; private static Method sigarIoWaitMtd = null; private static boolean useSunJdk6; private static final MemoryMXBean mbean = ManagementFactory.getMemoryMXBean(); static { preferSigar = Boolean.parseBoolean(Settings.get("xbird.perfmon.perfer_sigar")); if (preferSigar) { initializeSigar(); } else { initializeSunJdk(); } } private SystemUtils() { } private static void initializeSigar() { try { Object sigar = Class.forName("org.hyperic.sigar.Sigar").newInstance(); Method proxyMtd = Class.forName("org.hyperic.sigar.SigarProxyCache").getMethod("newInstance", sigar.getClass(), int.class); // Update caches every 2 seconds. sigarInstance = proxyMtd.invoke(null, sigar, 2000); sigarCpuPercMtd = sigarInstance.getClass().getMethod("getCpuPerc"); sigarCpuCombinedMtd = sigarCpuPercMtd.getReturnType().getMethod("getCombined"); sigarIoWaitMtd = sigarCpuPercMtd.getReturnType().getMethod("getWait"); } catch (Exception e) { LogFactory.getLog(SystemUtils.class).error("Failed to initilize Hyperic Sigar", e); } } private static void initializeSunJdk() { boolean useSunMx = false; if (IS_SUN_VM) { OperatingSystemMXBean mx = ManagementFactory.getOperatingSystemMXBean(); com.sun.management.OperatingSystemMXBean sunmx = (com.sun.management.OperatingSystemMXBean) mx; long testval = sunmx.getProcessCpuTime(); if (testval != -1L) { useSunMx = true; } } if (!useSunMx) { if (System.getProperty("xbird.use_jni") != null) { throw new IllegalStateException("Please set `xbird.use_jni' system property"); } try { System.loadLibrary("xbird_util_lang_SystemUtils"); } catch (UnsatisfiedLinkError le) { LogFactory.getLog(SystemUtils.class).warn( "Performance monitoring is not supported for this JVM. Please ensure that 'xbird.profiling' property is not enabled in your 'xbird.properties'"); } } useSunJdk6 = useSunMx; } public static float getJavaVersion() { return JAVA_VERSION_FLOAT; } private static float parseJavaVersion(String versionStr) { if (versionStr == null) { throw new IllegalArgumentException(); } // e.g., 1.3.12, 1.6 String str = versionStr.substring(0, 3); if (versionStr.length() >= 5) { str = str + versionStr.substring(4, 5); } return Float.parseFloat(str); } private static String getJavaVersion(String versionStr) { for (int i = 0; i < versionStr.length(); i++) { char c = versionStr.charAt(i); if (Character.isDigit(c)) { return versionStr.substring(i); } } return null; } public static boolean isSunVM() { return IS_SUN_VM; } public static boolean is64BitVM() { try { int bits = Integer.getInteger("sun.arch.data.model", 0).intValue(); if (bits != 0) { return bits == 64; } return System.getProperty("java.vm.name").indexOf("64") >= 0; } catch (Throwable t) { return false; } } public static boolean isEpollEnabled() { final String osname = AccessController.doPrivileged(new GetPropertyAction("os.name")); if ("SunOS".equals(osname)) { return true; } // use EPollSelectorProvider for Linux kernels >= 2.6 if ("Linux".equals(osname)) { String osversion = AccessController.doPrivileged(new GetPropertyAction("os.version")); final String[] vers = osversion.split("\\.", 0); if (vers.length >= 2) { try { final int major = Integer.parseInt(vers[0]); final int minor = Integer.parseInt(vers[1]); if (major > 2 || (major == 2 && minor >= 6)) { return true; } } catch (NumberFormatException x) { // format not recognized } } } return false; } public static int availableProcessors() { return NPROCS; } public static boolean isSendfileSupported() { return IS_OS_SUN_OS || (IS_OS_LINUX && getJavaVersion() >= 1.7f); } public static boolean isMunmapAvailable() { return !IS_OS_WINDOWS || getJavaVersion() >= 1.7f; } public static long getFreeMemory() { final Runtime runtime = Runtime.getRuntime(); return runtime.freeMemory(); } public static long getHeapFreeMemory() { MemoryUsage usage = mbean.getHeapMemoryUsage(); final long max = usage.getMax(); final long used = usage.getUsed(); final long free = max - used; return free; } public static long getHeapUsedMemory() { MemoryUsage usage = mbean.getHeapMemoryUsage(); final long used = usage.getUsed(); return used; } public static float getHeapFreeRatio() { MemoryUsage usage = mbean.getHeapMemoryUsage(); final long max = usage.getMax(); final long used = usage.getUsed(); final long free = max - used; return (float) free / (float) max; } public static int getHeapFreePercentage() { return (int) (getHeapFreeRatio() * 100f); } public static int countGC() { int count = 0; final List<GarbageCollectorMXBean> gclist = ManagementFactory.getGarbageCollectorMXBeans(); for (GarbageCollectorMXBean gcmx : gclist) { count += gcmx.getCollectionCount(); } return count; } /** * @return uptime in msec */ public static long getUptime() { final RuntimeMXBean mx = ManagementFactory.getRuntimeMXBean(); return mx.getUptime(); } public static double getCpuLoadAverage() { if (preferSigar) { final Double cpuload; try { cpuload = (Double) sigarCpuCombinedMtd.invoke(sigarCpuPercMtd.invoke(sigarInstance)); } catch (Exception e) { LogFactory.getLog(SystemUtils.class).error("Failed to obtain CPU load via Hyperic Sigar", e); return -1d; } return cpuload.doubleValue(); } else if (useSunJdk6) { OperatingSystemMXBean mx = ManagementFactory.getOperatingSystemMXBean(); com.sun.management.OperatingSystemMXBean sunmx = (com.sun.management.OperatingSystemMXBean) mx; double d = sunmx.getSystemLoadAverage(); if (d > 0) { return d / NPROCS; } return d; } else { return -1d; } } public static double getIoWait() { if (preferSigar) { final Double iowait; try { iowait = (Double) sigarIoWaitMtd.invoke(sigarCpuPercMtd.invoke(sigarInstance)); } catch (Exception e) { LogFactory.getLog(SystemUtils.class).error("Failed to obtain CPU iowait via Hyperic Sigar", e); return -1d; } return iowait.doubleValue(); } else { return -1d; } } /** return in nano-seconds */ @Deprecated public static long getProcessCpuTime() { if (preferSigar) { throw new UnsupportedOperationException( "SystemUtils#getProcessCpuTime() is not supported when using Hyperic Sigar"); } else if (useSunJdk6) { OperatingSystemMXBean mx = ManagementFactory.getOperatingSystemMXBean(); com.sun.management.OperatingSystemMXBean sunmx = (com.sun.management.OperatingSystemMXBean) mx; return sunmx.getProcessCpuTime(); } else { return _getProcessCpuTime() * 1000000L; /* milli to nano (10^6) */ } } public static CPUInfo getCPUInfo(CPUInfo prev) { final long cpuTime = getProcessCpuTime(); final long upTime = getUptime(); final long elapsedCpu = cpuTime - prev.cpuTime; long elapsedUp = upTime - prev.upTime; if (elapsedUp == 0L) { elapsedUp = 1L; } // nano (10^6) * percent (100) = 10000F final float cpuUsage = Math.min(99F, elapsedCpu / (elapsedUp * 10000F * NPROCS)); return new CPUInfo(cpuTime, upTime, cpuUsage); } public static final class CPUInfo { final long cpuTime; final long upTime; final float cpuLoad; public CPUInfo() { this.cpuTime = getProcessCpuTime(); this.upTime = getUptime(); this.cpuLoad = 1L; } public CPUInfo(long procCpuTime, long upTime, float cpuUsage) { this.cpuTime = procCpuTime; this.upTime = upTime; this.cpuLoad = cpuUsage; } public float getCpuLoad() { return cpuLoad; } } /** gets Process CPU time in milli-seconds */ private native static long _getProcessCpuTime(); }