Linux下java获取CPU、内存、磁盘IO、网络IO

获取linux命令运行结果

下面的代码用于获取运行一个Linux命令之后的结果,函数返回一个字符串,即命令的运行结果

import java.io.IOException;
import java.io.InputStreamReader;
import java.io.LineNumberReader;

public class Runcommand {
    public static String runCommand(String CMD) {
        String info = "";
        try {
            Process pos = Runtime.getRuntime().exec(CMD);
            pos.waitFor();
            InputStreamReader isr = new InputStreamReader(pos.getInputStream());
            LineNumberReader lnr = new LineNumberReader(isr);
            String line = "";
            while ((line = lnr.readLine()) != null) {
                info = info + line + "\n";
            }
        } catch (IOException e) {
            info = e.toString();
        } catch (Exception e) {
            info = e.toString();
        }
        return info;
    }
}

以下我所获取的数据都简单地用json封装了一下

获取CPU使用率

通过运行Linux命令cat /proc/stat获取
cat /proc/stat运行结果
第一行的数值表示的是CPU总的使用情况,所以我们只需用第一行的数字计算。
这里显示的数据单位是jiffies,jiffies是内核中的一个全局变量,用来记录自系统启动以来产生的节拍数,在linux中,一个节拍大致可理解为操作系统进程调度的最小时间片,不同linux内核可能值有不同,通常在1ms到10ms之间。
每个数据代表不同的时间,具体每个数据的含义可在Linux中通过/proc/stat等文件计算Cpu使用率中了解

总的cpu时间totalCpuTime = user + nice + system + idle + iowait + irq + softirq + stealstolen +guest
idle是CPU的空闲时间,即没有使用的时间
所以CPU利用率为:1-idle/totalCpuTime
使用一秒内CPU的使用率充当实时的CPU的实时使用率,即CPU实时使用率为:1-(idle2-idle1)/(totalCpuTime2-totalCpuTime1)
代码如下

import net.sf.json.JSONObject;

public class AcquireCPU {
    private static String CMD = "cat /proc/stat";

    public static double getCPUUsageRate() {
        String info1 = null;
        String info2 = null;
        try {
            info1 = Runcommand.runCommand(CMD);
            Thread.sleep(1000);//隔一秒再运行一次
            info2 = Runcommand.runCommand(CMD);
        } catch (Exception e) {

        }

        double total1 = 0.0;// 第一次获取的CPU使用总时间
        double total2 = 0.0;// 第二次获取的CPU使用总时间
        double CPUUsageRate = 0.0;// CPU使用率
        String[] data1 = info1.split("\n");
        String[] data2 = info2.split("\n");
        String[] strdata1 = data1[0].split(" +");
        String[] strdata2 = data2[0].split(" +");
        int[] numdata1 = new int[strdata1.length - 1];
        int[] numdata2 = new int[strdata2.length - 1];
        for (int i = 1; i < strdata1.length; i++) {
            numdata1[i - 1] = Integer.parseInt(strdata1[i]);
            total1 += numdata1[i - 1];
            numdata2[i - 1] = Integer.parseInt(strdata2[i]);
            total2 += numdata2[i - 1];
        }
        double idle1 = numdata1[3];// CPU未使用的时间
        double idle2 = numdata2[3];// CPU未使用的时间
        System.out.println(info1);
        System.out.println(info2);
        return CPUUsageRate = 1.0 - (idle2 - idle1) / (total2 - total1);//CPU使用率

    }

    public static JSONObject toJson(double CPUUsageRate) {//封装成json数据
        JSONObject json = new JSONObject();
        json.put("CPUUsageRate", CPUUsageRate);
        return json;
    }

    public static void main(String[] args) {
        // System.out.println("CPU使用率:"+getCPUUsageRate());
        double m = getCPUUsageRate();
        System.out.println("CPU使用率:" + m);
        System.out.println(toJson(m));
    }
}

获取内存大小和内存使用率

在Linux下查看内存我们一般用free命令:
free命令运行结果
下面是对这些数值的解释(单位kb):
Mem:
total:总计物理内存的大小。
used:已使用多大。
free:可用有多少。
shared:多个进程共享的内存总额。
buff/cache:磁盘缓存的大小。
available:可以使用的内存总量。
Swap(交换区的信息):
total:交换的总量。
used:使用量。
free:空闲的交换区。

对于应用程序来说,buff/cache 是等于可用的,因为buff/cache是为了提高文件读取的性能,当应用程序需在用到内存的时候,buff/cache会很快地被回收。
所以从应用程序的角度来说,可用内存=free+buff/cache=total-used
如上例:111552+243544=2028536-1673440=355096
内存使用率计算为:used/total
代码如下:

import net.sf.json.JSONObject;

public class AcquireMemory {
    private static int memorySize;//内存大小
    private static double memoryUsageRate;//内存使用率
    private static String CMD = "free";



public static JSONObject getMemorySize(String info){
    JSONObject json = new JSONObject();
    String[] data=info.split(" +");
    memorySize=Integer.parseInt(data[7]);
    json.put("memorySize", memorySize);
    return json;
}
public static JSONObject geteMemoryUsageRate(String info){
    JSONObject json = new JSONObject();
    String[] data=info.split(" +");
    double total=Double.parseDouble(data[7]);//内存总大小
    double used=Double.parseDouble(data[8]);//已使用内存大小
    memoryUsageRate = used/total;
    json.put("memoryUsageRate", memoryUsageRate);
    return json;
}

    public static void main(String[] args) {
        String info = Runcommand.runCommand(CMD);
        System.out.println(info);
        System.out.println(getMemorySize(info));
        System.out.println(geteMemoryUsageRate(info));
    }

}

获取磁盘IO

通过运行iostat -d -x 1 2命令获取磁盘的IO,后面的1代表间隔一秒,2代表获取两次,因为主要想要获取实时的磁盘IO,而仅仅执行iostat -d -x 的话,获取的数据是从系统启动以来的平均数据,这里第二次输出的数据是从上次输出之后统计的,即一秒前,所以也是以1秒的数据来近似代表实时的磁盘IO
iostat -d -x 1 2运行命令结果
下面介绍一下每项数据的意义:
rrqm/s:每秒进行merge的读操作数目。即delta(rmerge)/s
wrqm/s:每秒进行merge的写操作数目。即delta(wmerge)/s
r/s:每秒完成的读I/O设备次数。即delta(rio)/s
w/s:每秒完成的写I/0设备次数。即delta(wio)/s
rKB/s:每秒读K字节数。
wKB/s:每秒写K字节数。
avgrq-sz:平均每次设备I/O操作的数据大小(扇区)。即delta(rsect+wsect)/delta(rio+wio)
avgqu-sz:平均I/O队列长度。即delta(aveq)/s/1000(因为aveq的单位为毫秒)
await:平均每次设备I/O操作的等待时间(毫秒)。即delta(ruse+wuse)/delta(rio+wio)
svctm:平均每次设备I/O操作的服务时间(毫秒)。即delta(use)/delta(rio+wio)
%util:一秒中有百分之多少的时间用于I/O操作,或者说一秒中有多少时间I/O队列是非空的。即delta(usr)/s/1000(因为use的单位为毫秒)

所以直接获取结果的rKB/s和wKB/s即可

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

public class AcquireDiskIO {
    public static String CMD = "iostat -d -x 1 2";

    public static JSONArray getDiskIORate(String info) {
        String diskName = null;
        double rkb = 0.0;
        double wkb = 0.0;
        JSONObject json = new JSONObject();
        JSONArray jsonArray = new JSONArray();
        String[] data = info.split("\n");
        for (int i = 7; i < data.length; i++) {
            String[] numdata = data[i].split(" +");
            diskName = numdata[0];//磁盘名称
            rkb = Double.parseDouble(numdata[5]);//磁盘读数据速率
            wkb = Double.parseDouble(numdata[6]);//磁盘写数据速率
            json.put("diskName", diskName);
            json.put("rkb", rkb);
            json.put("wkb", wkb);
            jsonArray.add(json);
        }
        return jsonArray;//返回json数组
    }

    public static void main(String[] args) {
        String info = Runcommand.runCommand(CMD);
        System.out.println(info);
        System.out.println(getDiskIORate(info));
    }

}

获取网络IO

通过运行 cat /proc/net/dev命令来获取网络IO
cat /proc/net/dev运行命令结果
最左边Inter表示接口的名字,Receive表示收包,Transmit表示发送包;
bytes表示收发的字节数;
packets表示收发正确的包量;
errs表示收发错误的包量;
drop表示收发丢弃的包量;
这些数据也是自从系统启动以来的数据,所以用一秒内收发字节数来近似代表实时的网络IO

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

public class AcquireNetIO {
    private static String CMD = "cat /proc/net/dev";

    public static JSONArray getNetIO() {
        String info1 = null;
        String info2 = null;
        JSONObject json = new JSONObject();
        JSONArray jsonArray = new JSONArray();
        try {
            info1 = Runcommand.runCommand(CMD);
            Thread.sleep(1000);//隔一秒再执行一次
            info2 = Runcommand.runCommand(CMD);
            System.out.println(info1);
            System.out.println(info2);
        } catch (Exception e) {
            // TODO: handle exception
        }

        String[] data1 = info1.split("\n");
        String[] data2 = info2.split("\n");
        int receiveBytes1 = 0;
        int transmitBytes1 = 0;
        int receiveBytes2 = 0;
        int transmitBytes2 = 0;
        for (int i = 2; i < data1.length; i++) {
            String[] numdata1 = data1[i].trim().split(" +");
            String[] numdata2 = data2[i].trim().split(" +");
            receiveBytes1 = Integer.parseInt(numdata1[1]);
            transmitBytes1 = Integer.parseInt(numdata1[9]);
            receiveBytes2 = Integer.parseInt(numdata2[1]);
            transmitBytes2 = Integer.parseInt(numdata2[9]);

            int receiveBytes = receiveBytes2 - receiveBytes1;
            int transmitBytes = transmitBytes2 - transmitBytes1;
            json.put("Interface", numdata1[0]);//端口名称
            json.put("receiveBytes", receiveBytes);//端口一秒内接收的字节数
            json.put("transmitBytes", transmitBytes);//端口一秒内发送的字节数
            jsonArray.add(json);
            // System.out.println(numdata1[0]+" receiveBytes:" + receiveBytes +
            // " bytes transmitBytes:" + transmitBytes + " bytes");
        }
        return jsonArray;//返回json数组
    }

    public static void main(String[] args) {
        System.out.println(getNetIO());
    }
}
  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值