2017-06-23 109 views
0

我正在研究一個至少15歲的應用程序。我正在努力提高具有大約10K行代碼的特定流的性能。這個流程涉及在JMS主題上向外部系統發送信息。在解決那些我已經節省了一些時間的問題後,我發現了在創建和緩存會話時遇到的問題。現在我想進一步提高性能。爲此,我需要瀏覽整個10K行代碼並確定我在哪裏節省時間。該流程分爲三個部分 - 第一部分創建批量的單個請求並執行一些操作(線程池大小爲15) 第二部分從第一部分獲取輸入並進行一些更多處理(10個線程的線程池) 第三部分從第二部分取得輸入並做一些更多的處理(10個線程的線程池)測量Java應用程序的性能

我不能增加線程的數量,因爲資源是有限的,這不是應用程序中的唯一流(我的配置是 - 2個套接字,每個插槽12個核心和每個核心2個線程)。另外,我沒有太多的自由來玩這個遊戲,因爲這些第一,第二和第三部分也在其他地方使用。

要確定我已經創建了包含日誌語句一個ThreadLocal變量一類的執行時間,下面是代碼:

public class ExecutionTraceManager { 

private static Category cat = Category.getInstance(ExecutionTraceManager.class.getCanonicalName()); 

private static final ThreadLocal<Tracer> traceContainer = new ThreadLocal<Tracer>() { 
    @Override 
    protected Tracer initialValue() { 
     return new ExecutionTraceManager().new Tracer(); 
    } 
}; 

public static void addTrace(String trace) { 
    traceContainer.get().addTrace(trace); 
} 

public static void printTrace(){ 
    ArrayList<String> trace = traceContainer.get().trace; 
    StringBuffer buffer = new StringBuffer(); 
    for(String current : trace){ 
     buffer.append(current).append("\n"); 
    } 

    cat.info(buffer); 
} 

public class Tracer { 
    ArrayList<String> trace = new ArrayList<String>(); 
    long startTime = System.nanoTime(); 
    boolean init = false; 
    public void addTrace(String traceMessage) { 
     if(!init){ 
      startTime = System.nanoTime(); 
      init = true; 
     } 
     StringBuffer buffer = new StringBuffer("Time taken till [ ") 
       .append(traceMessage) 
       .append(" ] is : " 
         + ((System.nanoTime() - startTime)/1000000.0)); 
     trace.add(buffer.toString()); 
    } 
} 

在我的代碼,我只是叫ExecutionTraceManager.addTrace一旦線程完成任務我調用printTrace並重置本地線程,以便下一次該線程處理下一個請求時,它會看到空蹤跡列表。

這對我很好,但我想了解什麼是其他方式來確定哪些代碼花費時間(因爲我有~10行代碼)。專業人員採取什麼方法來處理這些問題。

+4

使用分析器。例如VisualVM https://docs.oracle.com/javase/8/docs/technotes/guides/visualvm/profiler.html –

+0

使用類似yourkit的分析器並測量掛壁時間。 – Rnet

+0

謝謝Stephen C,JVisualVM幫助 –

回答

1

使用指標收集庫

使用指標收集庫像Metrics是,在我看來,不是滾動您自己,因爲它與採樣交易和擁有各種指標的實現(定時器,直方圖等)更好的解決方案。 本質上添加這樣的代碼:

private final Timer responses = metrics.timer(name(RequestHandler.class, "responses")); 

// in the method 
    try (Timer.Context ctx = responses.time()) { 
     // run operations 
    } 
} 

這產生的執行時間可以查詢關於各種百分位數(99,95,90,等等)的直方圖。 它還具有可以在生產系統中運行並收集指標的優勢。

我比分析器更喜歡這種方法,因爲分析器傾向於產生非常密集的輸出,很難映射到應用程序的功能。 應用程序級別的計時度量標準會生成更易於理解和採取行動的度量標準。

使用分析器

您也可以使用像在Mission Control的飛行記錄儀探查,雖然在生產環境中運行它需要支付許可證。 正如在其他答案中提到的那樣,還有其他一些工具,如VisualVM,可以使用分析器。