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

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

cpu使用率如何计算

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

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

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

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

每隔3秒查询计算一次。

java实现过程

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

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

Cpu[] cpus = this.sigar.getCpuList();//获取cpu信息

long time = 0L;

for (int i = 0; i 

time += cpus[i].getTotal();

}

return time;

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

接下来就是获取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。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值