xbird.util.system.SystemUtils.java Source code

Java tutorial

Introduction

Here is the source code for xbird.util.system.SystemUtils.java

Source

/*
 * @(#)$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();

}