2017-06-23 54 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,可以使用分析器。