获取进程CPU使用率

时间:2016-10-30 10:01:57

标签: java multithreading process cpu-usage jmx

我有一个程序加载一个包含一些信息的文本文件,并根据该信息运行多个线程。每个线程都是一个进程。这是我的代码:

public class runMultiClient {
public static void main(String[] args){
    List<Process> PRlist = new ArrayList<Process>();
    List<String[]> commandsList = new ArrayList<String[]>();
    boolean running = true;

    if (args.length == 2 && args[0].matches("-f")){
        String dir = System.getProperty("user.dir");
        String path = dir + "/" + args[1];
        FileReader fr;
        try {
            fr = new FileReader(path);
            BufferedReader bf = new BufferedReader(fr);

            String line = "";
            while ((line = bf.readLine()) != null){
                String[] tk = line.split(" ");
                String[] cmd = {"java", "-jar", "Client.jar", "-a", tk[0], "-p", tk[1],
                        "-u", tk[2], "-pw", tk[3], "-m", tk[4], "-s", tk[5]};
                Process pr = new ProcessBuilder().inheritIO().command(cmd).start();
                PRlist.add(pr);
                commandsList.add(cmd);
                System.out.println(tk[4] + " streaming process is established.");
            }
        } 
        catch (FileNotFoundException ex) {ex.printStackTrace();} 
        catch (IOException ex) {ex.printStackTrace();}
    } else {
        System.out.println("No stream file was specified.");
    }
}}

在我的Client.jar文件中,我有一个监视该类的cpu负载的变量:

OperatingSystemMXBean osBean = ManagementFactory.getPlatformMXBean(OperatingSystemMXBean.class);
            cpuLoad = osBean.getProcessCpuLoad();

有什么办法可以从runMultiClient课程中找到该变量吗? 如果没有,有没有办法在正在运行的进程中使用OperatingSystemMXBean? 我试过了pr.getClass(),但它让我无处可去。 任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:2)

选项#1:添加代理库并通过HTTP公开JMX

您可以将Jolokia代理与您的受监控应用程序捆绑在一起(另一个类似的东西是SimpleJMX。它通过http / json公开JMX bean,因此这适用于与其他语言(如python(和super))的JMX进行交互从命令(例如)中进行故障排除时很舒服。之后,您可以通过apache http客户端等访问您感兴趣的mbeans。

选项#2:JMX客户端

启动受监控的应用程序时,通过添加以下参数来允许远程连接:

-Dcom.sun.management.jmxremote.port=9999 \
-Dcom.sun.management.jmxremote.authenticate=false \
-Dcom.sun.management.jmxremote.ssl=false 

然后你应该能够通过jconsole和手写的JMX客户端代码访问mbeans,就像the tutorial

一样

答案 1 :(得分:1)

不确定是否需要调用ProcessBuilder().inheritIO()以获取其他一些要求,但如果没有,则可以在Client.jar进程中启动一个守护程序线程,该进程会定期将cpu负载写入System.out。然后你的runMultiClient线程[s]可以从InputStream中读取那些代表进程的System.out的线程。或者,让线程接受命令并相应地打印。粗略的例子:

在衍生的Client.jar中运行它:

public static void startCmdListener() {
    try {
        Thread t = new Thread("CmdListener") {
            BufferedReader br = null;
            InputStreamReader isr = null;
            final OperatingSystemMXBean os = (OperatingSystemMXBean) ManagementFactoryHelper.getOperatingSystemMXBean();
            public void run() {
                try {
                    isr = new InputStreamReader(System.in);
                    br = new BufferedReader(isr);
                } catch (Exception ex) {
                    ex.printStackTrace(System.err);
                    return;
                } 
                try {
                    String cmd = null;
                    while(true) {
                        cmd = br.readLine();
                        if("cpu".equalsIgnoreCase(cmd)) {   // cpu command, print the process load
                            System.out.println(os.getProcessCpuLoad());
                        } else if("exit".equalsIgnoreCase(cmd)) {   // exit command, break
                            break;
                        }
                    }
                } catch (Exception ex) {
                    ex.printStackTrace(System.err);
                    return;
                } 

            }
        };
        t.setDaemon(true);
        t.start();
    } catch (Exception ex) {
        ex.printStackTrace(System.err);
    }
}

在runMultiClient中运行此命令以获取cpu加载:

public static double getCpu(OutputStream processIn, InputStream processOut) {
    PrintStream ps = null;
    BufferedReader br = null;
    InputStreamReader isr = null;

    try {
        ps = new PrintStream(processIn);
        isr = new InputStreamReader(processOut);
        br = new BufferedReader(isr);
        ps.println("cpu");
        ps.flush();         
        return Double.parseDouble(br.readLine());
    } catch (Exception ex) {
        throw new RuntimeException(ex);
    } finally {
        if(ps!=null) try { ps.close(); } catch (Exception x) {}
        if(br!=null) try { br.close(); } catch (Exception x) {}
        if(isr!=null) try { isr.close(); } catch (Exception x) {}
    }
}