java程序中线程cpu使用率计算

最近确实遇到题目上的刚需,也是花了一段时间来思考这个问题。java

cpu使用率如何计算

    计算使用率在上学那会就常常算,不过每每计算的是整个程序执行的时间段,如今忽然要实时计算还真有点无奈,时间段如何选择是个问题。最后根据现有的程序作参考,那就是Linux的top命令源码。linux

    top命令仍是c程序,加之开源,我直接采起相同的时间段和计算方法。c++

    先说说top是如何计算的,首先是从/proc/stat下读取cpu的使用时间,其次就是/proc/pid/stat获取进程的cpu时间,/proc/pid/task里获取这个进程里每一个线程的id,而后继续从stat里查找cpu的使用时间。windows

    线程cpu的利用率=线程运行的时间差(包括用户态+核心态+。。。。)/cpu运行时间之差(用户态+核心态+io+.....)api

    每隔3秒查询计算一次。jvm

java实现过程

    既然要获取cpu信息,我查询了不少方法,最终肯定,java自己是作不到的(windows可没有/proc这样的文件给你查看),要借助c/c++来处理,本来我调用函数都查好了,就差写jni了,结果有人给我推荐了sigar。是就是基于本地库实现的,不过他已经把本地库这些都准备好了,基本每一个平台都有,这样提供了很大的方便。接下来就是对这个库的使用过程了。函数

    根据给出的参考例子和相关api文档。咱们导入Jar包后须要继承SigarCommandBase这个类,咱们一切的操做基本依靠父类的成员变量sigarthis

    Cpu[] cpus = this.sigar.getCpuList();//获取cpu信息
    long time = 0L;
    for (int i = 0; i < cpus.length; i++) {
      time += cpus[i].getTotal();
    }
    return time;

    先获取到cpu的信息,而后直接经过getTotal来获得当前cpu的运行时间,你能够用cpus获取到cpu在核心态运行时间等等,我最后尝试加起来和getTotal小有出入,差异不大,因此采用getTotal就能够了,这样就能获取cpu运行时间,第二次采集时也就知道时间差了。spa

    接下来就是获取java线程信息这些了,依然仍是算差值。线程

   ThreadMXBean mx = ManagementFactory.getThreadMXBean();
    long[] threadIds = mx.getAllThreadIds();
    ThreadInfo[] threadInfos = mx.getThreadInfo(threadIds);

    经过上面的代码就能够获取到如今进程里每一个线程的信息。

  long time = mx.getThreadCpuTime(threadId);

    再经过getThreadCpuTime方法根据tid来获取到该线程在cpu上运行总时间,java文档上是这么写的:返回指定 ID 的线程的总 CPU 时间(以毫微秒为单位)。这里的单位是毫微秒的单位,要注意转换。

    我保存线程信息是用一个map,主键是线程id,这里你们就须要稍微注意一下,我更建议是线程id+线程名字的手段来作主键,tid是标识惟一一个线程,咱们假设a线程的id是34,若是a线程死掉以后,b线程启动,jvm会不会把34号标识给b线程呢,这里我不敢确定,我感受是会的。在linux的文件描述符也是惟一标识一个文件的,可是你一个文件关闭后,再开一个,确定会占用到相同的描述符。因此我感受线程的id也是如此,id是标识了惟一的线程,可是线程死掉,从新分配的话,这样也代码没必要要的困扰。

    剩下的就是算差值来计算使用率了,记得把动态库的位置加上,-Djava.library.path="位置",windows下能够加到path路径下,linux能够指定LD_LIBARARY_PATH。

相关文章
相关标签/搜索