今天学习一下Arthas是如何打印出当前机器上的所有<em>Java</em>线程的和调用控制台的,这个技术点不清楚,我们从Arthas的代码中找出实现,学习下知识点,在下次自己用的时候可以有思路,但是Arthas的代码量如此之多,在没人带的
2021-05-16 14:00:38
點贊再看,養成讚美的習慣,微信搜一搜【香菜聊遊戲】關注我。
今天學習一下Arthas是如何打印出當前機器上的所有Java執行緒的和呼叫控制檯的,這個技術點不清楚,我們從Arthas的程式碼中找出實現,學習下知識點,在下次自己用的時候可以有思路,但是Arthas的程式碼量如此之多,在沒人帶的情況下怎麼讀程式碼吶?
1、如何根據表現查程式碼
1.1 偵錯斷點,因為上篇文章我已經介紹了怎麼偵錯,能偵錯的程式碼一定要偵錯,斷電跟蹤程式碼,因此我也想偵錯的方式去跟蹤程式碼,但是我在打上斷點的時候,並且使用命令之後,啟動之後發現斷點沒有生效,思考下為什麼沒有生效?上期的文章有答案,偵錯程式的原理。
java -jar arthas-boot.jar
1.2 讀程式碼,既然要讀程式碼了就不能怕讀程式碼,讀程式碼不需要任何的環境,不要任何的測試,不需要任何的條件,只要跟著程式碼的走向即可。帶好小本,記錄好自己的理解。
1.3 舉例
看到列印的日誌如下,既然想看他的源碼, 從運行的日誌列印,分析日誌的內容,發現列印的也沒有參數,直接拷貝。不要想那麼多,直接全局搜尋,找到下面的不少用處,我們稍微掃一下就看到了很多地方不是程式碼呼叫,我們直接定位到Arthas-boot,OK,我們找到了這個程式碼的源頭,直接進入理解階段。
2、如何實現自己的java 程序列表
在跟蹤程式碼程式碼的過程中,也要理清楚思路,作者到底是怎麼做成這件事,如果是你 會有什麼樣的思路,如果你的思路剛好和作者的不謀而合,我相信你理解起來程式碼就很簡單,如果你的思路和作者的不同,我們應該思考為什麼Arthas的作者這麼做,你的方案是不是更好,盡信書不如無書!我們帶著問題開始吧。
1、訪問環境變數,如何找到jps
1.1 如何讀取電腦的環境變數 :System.getProperty("java.home")
1.2 jps 是什麼?jps是java提供的一個顯示當前所有java程序pid的命令,我們發現了事情的核心。
1.3 如何找到jps ?jps 的路徑可能不同,或者Arthas運行的系統不同,作者直接列出了所有的可能路徑,總有一個蒙準。
privatestaticFilefindJps() {// Try to find jps under java.home and System env JAVA_HOMEStringjavaHome=System.getProperty("java.home");String[] paths= { "bin/jps", "bin/jps.exe", "../bin/jps", "../bin/jps.exe" };List<File>jpsList=newArrayList<File>();for (Stringpath : paths) {FilejpsFile=newFile(javaHome, path);if (jpsFile.exists()) {AnsiLog.debug("Found jps: "+jpsFile.getAbsolutePath());jpsList.add(jpsFile);} }//省略了不重要的程式碼 }
2、jps命令格式
問題:jps 命令 的執行格式
看程式碼中jps 有兩種方式,一種加V ,資訊更多,一種不加v 僅僅列出了所有的執行緒。
String[] command = null; if (v) { command = new String[] { jps, "-v", "-l" }; } else { command = new String[] { jps, "-l" }; } List<String> lines = ExecutingCommand.runNative(command);
3、運行cmd
我們看到Arthas是在控制檯視窗中運行的,我們的問題是:
3.1 怎麼執行命令?使用runtime的exec介面,直接呼叫系統命令
3.2 Process 是什麼?process是代表一個程序,啟動的控制檯視窗就是一個Process
publicstaticList<String>runNative(String[] cmdToRunWithArgs) {Processp=null;try {p=Runtime.getRuntime().exec(cmdToRunWithArgs);
4、讀取輸出並編號
程式碼所在位置:com.taobao.arthas.common.ExecutingCommand#runNative(java.lang.String[])
問題:怎麼讀取控制檯視窗的輸出,或者說接管控制檯視窗,使用process.getInputStream() 獲取控制檯的輸出。
ArrayList<String> sa = new ArrayList<String>(); BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream())); try { String line; while ((line = reader.readLine()) != null) { sa.add(line); }
3、一步步實現程式碼
核心技術點是呼叫jps.exe 的命令如何執行命令 jps -l輸出控制檯輸出完整程式碼:packagecom.taobao.arthas.core;importjava.io.BufferedReader;importjava.io.File;importjava.io.IOException;importjava.io.InputStreamReader;/*** 獲得機器上所有Java執行緒
* @author 香菜*/publicclassAain {publicstaticvoidmain(String[] args) throwsIOException {//1、獲取jps地址,執行完成之後可以看下對應的路徑下是否有jps.exeStringjpsPath=getJpsPath();//2、運行cmdrunCmd(jpsPath);}/*** 讀取輸出* @param reader* @throws IOException*/privatestaticvoidreadOutput(BufferedReaderreader) throwsIOException {try {Stringline;while ((line=reader.readLine()) !=null) {System.out.println(line); } } catch (Exceptione) {e.printStackTrace(); } finally {reader.close(); } }/*** 運行cmd* @param jpsPath* @throws IOException*/privatestaticvoidrunCmd(StringjpsPath) throwsIOException {String[] cmdStr=newString[] { jpsPath, "-l" };Processp=null;try {p=Runtime.getRuntime().exec(cmdStr); } catch (Exceptione) {return; }readOutput(newBufferedReader(newInputStreamReader(p.getInputStream()))); }/*** 獲得jps.exe 的地址* @return*/privatestaticStringgetJpsPath() {StringjavaHome=System.getProperty("java.home");// 因為在windows環境下演示,只處理window 環境returnnewFile(javaHome, "../bin/jps.exe").getAbsolutePath(); }}
運行結果:
4、總結:
每個問題的解決,最初的樣子都很簡單,只是因為加了異常處理,或者特殊需求,或者更全面才成為最終的樣子,我們要從複雜的程式碼中看到技術的本質問題,而不是在大量的程式碼中迷失。
今天主要學會了怎麼呼叫控制檯,讀取控制檯輸出,以及jps的使用,你都明白了嗎?
相關文章
今天学习一下Arthas是如何打印出当前机器上的所有<em>Java</em>线程的和调用控制台的,这个技术点不清楚,我们从Arthas的代码中找出实现,学习下知识点,在下次自己用的时候可以有思路,但是Arthas的代码量如此之多,在没人带的
2021-05-16 14:00:38
从电商的配置上看是16GB内存,512GB<em>固态硬盘</em>。就我自己的观点而言,轻薄笔记本最好选择16GB的,毕竟集显也要用掉内存。来看看外观吧,都说女生是颜值党,其实男生也是。灰色的铝镁合金外壳,经典的阳极氧化喷砂工艺,作为
2021-05-16 14:00:02
关于这个投票,很多火箭球迷选择离开。有意思的是,沃尔本场也参与了这个投票,并被该媒体截图,沃尔用自己的INS账号选择了“会离开”的选项。与此同时,NBA名记Tim <em>Mac</em>Mahon做客某一档节目时,谈到沃尔说到:沃尔离开只
2021-05-16 13:30:58
投多了还会显示风险异常,所以投几个号之后就需要开飞行模式清理缓存,还要下很多个<em>浏览器</em>,这样才能顺利投上票。 每个打投组和奶卡组还有发号的小组长,打投的人需要每天结合实际的时间去申请领号,每天晚上还
2021-05-16 13:30:39
因此,如果经常出现一些睡眠问题,比如说失眠难以入睡,或者是即使睡着后,半夜惊醒的情况,可能就是肝气郁结所造成的。调理办法 睡前远离手机、<em>ipad</em>:现在的生活中,无论大人、小孩还是老人,几乎人人都离不开电子产品,特别
2021-05-16 13:30:26
今年入手<em>iPad</em>2020的话,其实现在就可以入手 <em>iPad</em>2020本身它那个溢价就空间比较小,然后呢教育优惠在目前来说性价比是比较高的。618期间的话,<em>iPad</em>2020它这个价格可能跟教育优惠差不了太多的。<
2021-05-16 13:30:14