原文地址:https://www.imooc.com/article/27374

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

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 < cpus.length; 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。

java程序中线程cpu使用率计算的更多相关文章

  1. 定位java程序中占用cpu最高的线程堆栈信息

    找出占用cpu最高的线程堆栈信息 在java编码中,有时会因为粗心导致cpu占用较高的情况,为了避免影响程序的正常运行,需要找到问题并解决.这里模拟一个cpu占用较高的场景,并尝试定位到代码行. 示例 ...

  2. 【并发编程】一个最简单的Java程序有多少线程?

    一个最简单的Java程序有多少线程? 通过下面程序可以计算出当前程序的线程总数. import java.lang.management.ManagementFactory; import java. ...

  3. SQL函数TIMEDIFF在Java程序中使用报错的问题分析

    需求背景 (读者可略过)司机每天从早到晚都会去到不同的自动售货机上补货,而且补货次数和路线等也是因人而异,补货依据是由系统优化并指派.但是目前系统还无法实施有效指挥和优良的补货策略,司机的补货活动因此 ...

  4. java程序中的经常出现的的异常处理课后总结

    一.JDK中常见的异常情况 1.常见异常总结图 2.java中异常分类 Throwable类有两个直接子类: (1)Exception:出现的问题是可以被捕获的 (2)Error:系统错误,通常由JV ...

  5. Linux上从Java程序中调用C函数

    原则上来说,"100%纯Java"的解决方法是最好的,但有些情况下必须使用本地方法.特别是在以下三种情况: 需要访问Java平台无法访问的系统特性和设备: 通过基准测试,发现Jav ...

  6. 在网页程序或Java程序中调用接口实现短信猫收发短信的解决方案

    方案特点: 在网页程序或Java程序中调用接口实现短信猫收发短信的解决方案,简化软件开发流程,减少各应用系统相同模块的重复开发工作,提高系统稳定性和可靠性. 基于HTTP协议的开发接口 使用特点在网页 ...

  7. 如何在java程序中调用linux命令或者shell脚本

    转自:http://blog.sina.com.cn/s/blog_6433391301019bpn.html 在java程序中如何调用linux的命令?如何调用shell脚本呢? 这里不得不提到ja ...

  8. Java程序中调用Python脚本的方法

    在程序开发中,有时候需要Java程序中调用相关Python脚本,以下内容记录了先关步骤和可能出现问题的解决办法. 1.在Eclipse中新建Maven工程: 2.pom.xml文件中添加如下依赖包之后 ...

  9. 在java程序中访问windows有用户名和密码保护的共享目录

    在java程序中访问windows有用户名和密码保护的共享目录 Posted on 2015-11-20 14:03 云自无心水自闲 阅读(3744) 评论(0)  编辑  收藏 --> Jav ...

随机推荐

  1. MySQL 关于case when结合group by用时的写法举例

    原表是个员工档案,共583人,但case when结合group by用时,写法不同,其出来的结果也不同 例1: select distinct a.Branch,case when kultur = ...

  2. HTML5: HTML5 Geolocation(地理定位)

    ylbtech-HTML5: HTML5 Geolocation(地理定位) 1.返回顶部 1. HTML5 Geolocation(地理定位) HTML5 Geolocation(地理定位)用于定位 ...

  3. HP Server BIOS实验报告

    原文链接http://www.hpiss.com/3924.html 注意:红色字体为HP手册中查找到的资源,及个人感觉应该注意的一些信息,个人翻译的也为红字体,网络中自行查找到的资源,以及询问各位师 ...

  4. 原生JavaScript 模拟alert对话框

    Window.prototype._alert = function() { //创建一个大盒子 var box = document.createElement("div"); ...

  5. html 局部打印

    首先有个调用的方法.printView(). function printView() { bdhtml = window.document.body.innerHTML;//获取当前页的html代码 ...

  6. Cocos2d-x之引擎框架简介

    |   版权声明:本文为博主原创文章,未经博主允许不得转载. 1.cocos2d-x的设计思想 cocos2d-x分为导演,场景,图层,精灵,节点: (1).导演(Director):控制整个游戏的场 ...

  7. Spring Data JPA one to one 共享主键关联

    /** * Created by xiezhiyan on 17-9-13. */@Entitypublic class Token { @Id @Column(name = "store_ ...

  8. python基础【第五篇】

    python第三节 1.整型及布尔值 1.1 进制转换 十进制 ----二进制 二进制 ----十进制 8421方法与普通计算 python中十进制转二进制示例:bin(51)>>> ...

  9. 线性方程组迭代算法——Jacobi迭代算法的python实现

    原理: 请看本人博客:线性方程组的迭代求解算法——原理 代码: import numpy as np max=100#迭代次数上限 Delta=0.01 m=2#阶数:矩阵为2阶 n=3#维数:3X3 ...

  10. Oracle如何杀同库不同实例的会话

    今天处理了一个生产上的问题,主要就是杀会话, 生产环境是Oracle11gR2 RAC:有同事开发报表,报表工具连接到数据库上特别嚣张,把内存pin住: Select s.INST_ID, s.Mac ...