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。
總結
以上是生活随笔為你收集整理的java 线程 cpu_java程序中线程cpu使用率计算的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 抓包mysql协议_Mysql 通信协议
- 下一篇: mac java sh_怎么在Mac上下