首页 > 代码库 > java不用jni,也可以获得当前系统性能信息

java不用jni,也可以获得当前系统性能信息

最近做个项目,就是要取得cpu占有率等等的系统信息,一开始以为要用动态链接库了,但后来发现可以像下面这样做,不去调用jni,这样省去了很多看新技术的时间o(∩_∩)o...

在Java中,可以获得总的物理内存、剩余的物理内存、已使用的物理内存等信息,下面例子可以取得这些信息,并且获得在Windows下的内存使用率。
     首先编写一个MonitorInfoBean类,用来装载监控的一些信息,包括物理内存、剩余的物理内存、已使用的物理内存、内存使用率等字段,该类的代码如下:

package com.amgkaka.performance;/** *//** * 监视信息的JavaBean类. * @author  amg * @version 1.0  * Creation date: 2008-4-25 - 上午10:37:00 */public class MonitorInfoBean {    /** *//** 可使用内存. */    private long totalMemory;        /** *//** 剩余内存. */    private long freeMemory;        /** *//** 最大可使用内存. */    private long maxMemory;        /** *//** 操作系统. */    private String osName;        /** *//** 总的物理内存. */    private long totalMemorySize;        /** *//** 剩余的物理内存. */    private long freePhysicalMemorySize;        /** *//** 已使用的物理内存. */    private long usedMemory;        /** *//** 线程总数. */    private int totalThread;        /** *//** cpu使用率. */    private double cpuRatio;    public long getFreeMemory() {        return freeMemory;    }    public void setFreeMemory(long freeMemory) {        this.freeMemory = freeMemory;    }    public long getFreePhysicalMemorySize() {        return freePhysicalMemorySize;    }    public void setFreePhysicalMemorySize(long freePhysicalMemorySize) {        this.freePhysicalMemorySize = freePhysicalMemorySize;    }    public long getMaxMemory() {        return maxMemory;    }    public void setMaxMemory(long maxMemory) {        this.maxMemory = maxMemory;    }    public String getOsName() {        return osName;    }    public void setOsName(String osName) {        this.osName = osName;    }    public long getTotalMemory() {        return totalMemory;    }    public void setTotalMemory(long totalMemory) {        this.totalMemory = totalMemory;    }    public long getTotalMemorySize() {        return totalMemorySize;    }    public void setTotalMemorySize(long totalMemorySize) {        this.totalMemorySize = totalMemorySize;    }    public int getTotalThread() {        return totalThread;    }    public void setTotalThread(int totalThread) {        this.totalThread = totalThread;    }    public long getUsedMemory() {        return usedMemory;    }    public void setUsedMemory(long usedMemory) {        this.usedMemory = usedMemory;    }    public double getCpuRatio() {        return cpuRatio;    }    public void setCpuRatio(double cpuRatio) {        this.cpuRatio = cpuRatio;    }}

接着编写一个获得当前的监控信息的接口,该类的代码如下所示:

package com.amgkaka.performance;/** *//** * 获取系统信息的业务逻辑类接口. * @author amg * @version 1.0  * Creation date: 2008-3-11 - 上午10:06:06 */public interface IMonitorService {    /** *//**     * 获得当前的监控对象.     * @return 返回构造好的监控对象     * @throws Exception     * @author amgkaka     * Creation date: 2008-4-25 - 上午10:45:08     */    public MonitorInfoBean getMonitorInfoBean() throws Exception;}

该类的实现类MonitorServiceImpl如下所示:

package com.amgkaka.performance;import java.io.InputStreamReader;import java.io.LineNumberReader;import sun.management.ManagementFactory;import com.sun.management.OperatingSystemMXBean;/** *//** * 获取系统信息的业务逻辑实现类. * @author amg * @version 1.0 Creation date: 2008-3-11 - 上午10:06:06 */public class MonitorServiceImpl implements IMonitorService {    //可以设置长些,防止读到运行此次系统检查时的cpu占用率,就不准了    private static final int CPUTIME = 5000;    private static final int PERCENT = 100;    private static final int FAULTLENGTH = 10;    /** *//**     * 获得当前的监控对象.     * @return 返回构造好的监控对象     * @throws Exception     * @author amg     * Creation date: 2008-4-25 - 上午10:45:08     */    public MonitorInfoBean getMonitorInfoBean() throws Exception {        int kb = 1024;                // 可使用内存        long totalMemory = Runtime.getRuntime().totalMemory() / kb;        // 剩余内存        long freeMemory = Runtime.getRuntime().freeMemory() / kb;        // 最大可使用内存        long maxMemory = Runtime.getRuntime().maxMemory() / kb;        OperatingSystemMXBean osmxb = (OperatingSystemMXBean) ManagementFactory                .getOperatingSystemMXBean();        // 操作系统        String osName = System.getProperty("os.name");        // 总的物理内存        long totalMemorySize = osmxb.getTotalPhysicalMemorySize() / kb;        // 剩余的物理内存        long freePhysicalMemorySize = osmxb.getFreePhysicalMemorySize() / kb;        // 已使用的物理内存        long usedMemory = (osmxb.getTotalPhysicalMemorySize() - osmxb                .getFreePhysicalMemorySize())                / kb;        // 获得线程总数        ThreadGroup parentThread;        for (parentThread = Thread.currentThread().getThreadGroup(); parentThread                .getParent() != null; parentThread = parentThread.getParent())            ;        int totalThread = parentThread.activeCount();        double cpuRatio = 0;        if (osName.toLowerCase().startsWith("windows")) {            cpuRatio = this.getCpuRatioForWindows();        }                // 构造返回对象        MonitorInfoBean infoBean = new MonitorInfoBean();        infoBean.setFreeMemory(freeMemory);        infoBean.setFreePhysicalMemorySize(freePhysicalMemorySize);        infoBean.setMaxMemory(maxMemory);        infoBean.setOsName(osName);        infoBean.setTotalMemory(totalMemory);        infoBean.setTotalMemorySize(totalMemorySize);        infoBean.setTotalThread(totalThread);        infoBean.setUsedMemory(usedMemory);        infoBean.setCpuRatio(cpuRatio);        return infoBean;    }    /** *//**     * 获得CPU使用率.     * @return 返回cpu使用率     * @author amg     * Creation date: 2008-4-25 - 下午06:05:11     */    private double getCpuRatioForWindows() {        try {            String procCmd = System.getenv("windir")                    + "\\system32\\wbem\\wmic.exe process get Caption,CommandLine,"                    + "KernelModeTime,ReadOperationCount,ThreadCount,UserModeTime,WriteOperationCount";            // 取进程信息            long[] c0 = readCpu(Runtime.getRuntime().exec(procCmd));            Thread.sleep(CPUTIME);            long[] c1 = readCpu(Runtime.getRuntime().exec(procCmd));            if (c0 != null && c1 != null) {                long idletime = c1[0] - c0[0];                long busytime = c1[1] - c0[1];                return Double.valueOf(                        PERCENT * (busytime) / (busytime + idletime))                        .doubleValue();            } else {                return 0.0;            }        } catch (Exception ex) {            ex.printStackTrace();            return 0.0;        }    }    /** *//**     * 读取CPU信息.     * @param proc     * @return     * @author amg     * Creation date: 2008-4-25 - 下午06:10:14     */    private long[] readCpu(final Process proc) {        long[] retn = new long[2];        try {            proc.getOutputStream().close();            InputStreamReader ir = new InputStreamReader(proc.getInputStream());            LineNumberReader input = new LineNumberReader(ir);            String line = input.readLine();            if (line == null || line.length() < FAULTLENGTH) {                return null;            }            int capidx = line.indexOf("Caption");            int cmdidx = line.indexOf("CommandLine");            int rocidx = line.indexOf("ReadOperationCount");            int umtidx = line.indexOf("UserModeTime");            int kmtidx = line.indexOf("KernelModeTime");            int wocidx = line.indexOf("WriteOperationCount");            long idletime = 0;            long kneltime = 0;            long usertime = 0;            while ((line = input.readLine()) != null) {                if (line.length() < wocidx) {                    continue;                }                // 字段出现顺序:Caption,CommandLine,KernelModeTime,ReadOperationCount,                // ThreadCount,UserModeTime,WriteOperation                String caption = Bytes.substring(line, capidx, cmdidx - 1)                        .trim();                String cmd = Bytes.substring(line, cmdidx, kmtidx - 1).trim();                if (cmd.indexOf("wmic.exe") >= 0) {                    continue;                }                // log.info("line="+line);                if (caption.equals("System Idle Process")                        || caption.equals("System")) {                    idletime += Long.valueOf(                            Bytes.substring(line, kmtidx, rocidx - 1).trim())                            .longValue();                    idletime += Long.valueOf(                            Bytes.substring(line, umtidx, wocidx - 1).trim())                            .longValue();                    continue;                }                kneltime += Long.valueOf(                        Bytes.substring(line, kmtidx, rocidx - 1).trim())                        .longValue();                usertime += Long.valueOf(                        Bytes.substring(line, umtidx, wocidx - 1).trim())                        .longValue();            }            retn[0] = idletime;            retn[1] = kneltime + usertime;            return retn;        } catch (Exception ex) {            ex.printStackTrace();        } finally {            try {                proc.getInputStream().close();            } catch (Exception e) {                e.printStackTrace();            }        }        return null;    }        /** *//**     * 测试方法.     * @param args     * @throws Exception     * @author amg     * Creation date: 2008-4-30 - 下午04:47:29     */    public static void main(String[] args) throws Exception {        IMonitorService service = new MonitorServiceImpl();        MonitorInfoBean monitorInfo = service.getMonitorInfoBean();        System.out.println("cpu占有率=" + monitorInfo.getCpuRatio());                System.out.println("可使用内存=" + monitorInfo.getTotalMemory());        System.out.println("剩余内存=" + monitorInfo.getFreeMemory());        System.out.println("最大可使用内存=" + monitorInfo.getMaxMemory());                System.out.println("操作系统=" + monitorInfo.getOsName());        System.out.println("总的物理内存=" + monitorInfo.getTotalMemorySize() + "kb");        System.out.println("剩余的物理内存=" + monitorInfo.getFreeMemory() + "kb");        System.out.println("已使用的物理内存=" + monitorInfo.getUsedMemory() + "kb");        System.out.println("线程总数=" + monitorInfo.getTotalThread() + "kb");    }}

该实现类中需要用到一个自己编写byte的工具类,该类的代码如下所示:

package com.amgkaka.performance;/** *//** * byte操作类. * @author amg * @version 1.0  * Creation date: 2008-4-30 - 下午04:57:23 */public class Bytes {    /** *//**     * 由于String.subString对汉字处理存在问题(把一个汉字视为一个字节),因此在     * 包含汉字的字符串时存在隐患,现调整如下:     * @param src 要截取的字符串     * @param start_idx 开始坐标(包括该坐标)     * @param end_idx   截止坐标(包括该坐标)     * @return     */    public static String substring(String src, int start_idx, int end_idx){        byte[] b = src.getBytes();        String tgt = "";        for(int i=start_idx; i<=end_idx; i++){            tgt +=(char)b[i];        }        return tgt;    }}

运行下MonitorBeanImpl类,读者将会看到当前的内存、cpu利用率等信息。

 

(转自:http://kakaluyi.iteye.com/blog/211492)

 

java不用jni,也可以获得当前系统性能信息