java 线程 cpu_java程序中线程cpu使用率计算
最近確實(shí)遇到題目上的剛需,也是花了一段時(shí)間來思考這個(gè)問題。
cpu使用率如何計(jì)算
計(jì)算使用率在上學(xué)那會(huì)就經(jīng)常算,不過往往計(jì)算的是整個(gè)程序執(zhí)行的時(shí)間段,現(xiàn)在突然要實(shí)時(shí)計(jì)算還真有點(diǎn)無奈,時(shí)間段如何選擇是個(gè)問題。最后根據(jù)現(xiàn)有的程序做參考,那就是Linux的top命令源碼。
top命令還是c程序,加之開源,我直接采取相同的時(shí)間段和計(jì)算方法。
先說說top是如何計(jì)算的,首先是從/proc/stat下讀取cpu的使用時(shí)間,其次就是/proc/pid/stat獲取進(jìn)程的cpu時(shí)間,/proc/pid/task里獲取這個(gè)進(jìn)程里每個(gè)線程的id,然后繼續(xù)從stat里查找cpu的使用時(shí)間。
線程cpu的利用率=線程運(yùn)行的時(shí)間差(包括用戶態(tài)+核心態(tài)+。。。。)/cpu運(yùn)行時(shí)間之差(用戶態(tài)+核心態(tài)+io+.....)
每隔3秒查詢計(jì)算一次。
java實(shí)現(xiàn)過程
既然要獲取cpu信息,我查詢了很多方法,最終確定,java本身是做不到的(windows可沒有/proc這樣的文件給你查看),要借助c/c++來處理,原本我調(diào)用函數(shù)都查好了,就差寫jni了,結(jié)果有人給我推薦了sigar。是就是基于本地庫(kù)實(shí)現(xiàn)的,不過他已經(jīng)把本地庫(kù)這些都準(zhǔn)備好了,基本每個(gè)平臺(tái)都有,這樣提供了很大的方便。接下來就是對(duì)這個(gè)庫(kù)的使用過程了。
根據(jù)給出的參考例子和相關(guān)api文檔。我們導(dǎo)入Jar包后需要繼承SigarCommandBase這個(gè)類,我們一切的操作基本依靠父類的成員變量sigar
Cpu[]?cpus?=?this.sigar.getCpuList();//獲取cpu信息
long?time?=?0L;
for?(int?i?=?0;?i?
time?+=?cpus[i].getTotal();
}
return?time;
先獲取到cpu的信息,然后直接通過getTotal來得到當(dāng)前cpu的運(yùn)行時(shí)間,你可以用cpus獲取到cpu在核心態(tài)運(yùn)行時(shí)間等等,我最后嘗試加起來和getTotal小有出入,差別不大,所以采用getTotal就可以了,這樣就能獲取cpu運(yùn)行時(shí)間,第二次采集時(shí)也就知道時(shí)間差了。
接下來就是獲取java線程信息這些了,依然還是算差值。
ThreadMXBean?mx?=?ManagementFactory.getThreadMXBean();
long[]?threadIds?=?mx.getAllThreadIds();
ThreadInfo[]?threadInfos?=?mx.getThreadInfo(threadIds);
通過上面的代碼就可以獲取到現(xiàn)在進(jìn)程里每個(gè)線程的信息。
long?time?=?mx.getThreadCpuTime(threadId);
再通過getThreadCpuTime方法根據(jù)tid來獲取到該線程在cpu上運(yùn)行總時(shí)間,java文檔上是這么寫的:返回指定 ID 的線程的總 CPU 時(shí)間(以毫微秒為單位)。這里的單位是毫微秒的單位,要注意轉(zhuǎn)換。
我保存線程信息是用一個(gè)map,主鍵是線程id,這里大家就需要稍微注意一下,我更建議是線程id+線程名字的手段來做主鍵,tid是標(biāo)識(shí)唯一一個(gè)線程,我們假設(shè)a線程的id是34,如果a線程死掉之后,b線程啟動(dòng),jvm會(huì)不會(huì)把34號(hào)標(biāo)識(shí)給b線程呢,這里我不敢肯定,我感覺是會(huì)的。在linux的文件描述符也是唯一標(biāo)識(shí)一個(gè)文件的,但是你一個(gè)文件關(guān)閉后,再開一個(gè),肯定會(huì)占用到相同的描述符。所以我感覺線程的id也是如此,id是標(biāo)識(shí)了唯一的線程,但是線程死掉,重新分配的話,這樣也代碼不必要的困擾。
剩下的就是算差值來計(jì)算使用率了,記得把動(dòng)態(tài)庫(kù)的位置加上,-Djava.library.path="位置",windows下可以加到path路徑下,linux可以指定LD_LIBARARY_PATH。
總結(jié)
以上是生活随笔為你收集整理的java 线程 cpu_java程序中线程cpu使用率计算的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 抓包mysql协议_Mysql 通信协议
- 下一篇: 转正员工自评怎么写简短(员工自评怎么写简