2010-03-19 2 views
13

У меня есть приложение Spring, которое, как я считаю, имеет некоторые узкие места, поэтому я хотел бы запустить его с помощью профилировщика, чтобы определить, какие функции занимают сколько времени. Любые рекомендации, как я должен это делать?Профилирование приложения Java Spring

Я бегу STS, проект является проектом Maven, и я бегу Spring 3.0.1

+0

Профилирование приложения Spring не отличается от профилирования любого другого приложения Java. Возможно, вы захотите расширить вопрос, чтобы получить более широкий выбор ответов. – skaffman

ответ

15

Я сделал это, используя Spring AOP.

Когда-нибудь мне нужна информация о том, сколько времени требуется для выполнения некоторых методов в моем проекте (например, в примере контроллера).

В сервлета XML я положил

<aop:aspectj-autoproxy/> 

Кроме того, мне нужно создать класс для аспектов:

@Component 
@Aspect 
public class SystemArchitecture { 

    @Pointcut("execution(* org.mywebapp.controller..*.*(..))") 
    public void businessController() { 
    } 
} 

И профилировщика аспект:

@Component 
@Aspect 
public class TimeExecutionProfiler { 

    private static final Logger logger = LoggerFactory.getLogger(TimeExecutionProfiler.class); 

    @Around("org.mywebapp.util.aspects.SystemArchitecture.businessController()") 
    public Object profile(ProceedingJoinPoint pjp) throws Throwable { 
     long start = System.currentTimeMillis(); 
     logger.info("ServicesProfiler.profile(): Going to call the method: {}", pjp.getSignature().getName()); 
     Object output = pjp.proceed(); 
     logger.info("ServicesProfiler.profile(): Method execution completed."); 
     long elapsedTime = System.currentTimeMillis() - start; 
     logger.info("ServicesProfiler.profile(): Method execution time: " + elapsedTime + " milliseconds."); 

     return output; 
    } 

    @After("org.mywebapp.util.aspects.SystemArchitecture.businessController()") 
    public void profileMemory() { 
     logger.info("JVM memory in use = {}", (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory())); 
    } 
} 

Вот и все. Когда я запрашиваю страницу из моего webapp, информация о времени выполнения метода и использовании памяти JVM выводится в моем файле журнала webapp.

+0

Хе-хе, это на самом деле то же самое, что я использовал до сих пор. :-) Не совсем профилировщик, но вам предстоит пройти долгий путь :-) – niklassaers

+0

Говоря о том, что по какой-то причине это хорошо работает на моих бизнес-методах, но не на моих контроллерах. Любая идея, почему это может быть? – niklassaers

+0

Извините, вы не сказали этого в своем вопросе :) Если у вас вопрос о веб-приложении, и если вы используете контейнер сервлетов tomcat, вы можете использовать сервер SpringSource tc с функцией Spring-insight –

2

Вы можете использовать с открытым исходным кодом Java профилировщика, таких как Profiler4J:

http://profiler4j.sourceforge.net/

или Netbeans поставляется со встроенным профилировщиком, а Eclipse также имеет возможности профилирования, однако я нашел Profiler4J более простым в использовании, так как он имеет хороший график, показывающий вам наиболее трудоемкие методы.

Это хорошо работает в STS (eclipse), просто следуйте инструкциям на сайте.

+0

Спасибо за подсказку. Похоже, что последняя бета-версия Profiler4J была опубликована в 2006 году, является ли это еще активным проектом? – niklassaers

+0

Похоже, он не может быть активно развит, но когда я его использовал несколько месяцев назад, он работал хорошо. Я предполагаю, что он не будет развернут с вашим проектом, поэтому, если он будет работать как один раз, вам не нужно беспокоиться. Есть множество других, которые коммерчески доступны, иначе просто используйте тот, который поставляется с eclipse. –

+0

Хм, я попробовал это, но оказалось, что ни Call Graph, ни Tree Tree не заполнены, хотя я использовал все классы и классы прокси. Память и потоки работают хорошо, хотя – niklassaers

1

Мне понравился JRat, хотя, как и profiler4j, он, похоже, не активно развивается. В любом случае он был прост в использовании.

+0

Он выглядит очень прост в использовании, но когда я попробовал его, у меня возникли ошибки Nullpointer с точки зрения ткачества. Не знаю, почему, когда я отключил JRat, они ушли. Хотя я не удивлюсь, если это мои ошибки, но я не знаю, что их вызвало или откуда они пришли. : -I – niklassaers

3

Я рекомендую VisualVM для общего профилирования приложений. Он доступен в JDK версии 1.6_10, а imho намного быстрее и удобнее, чем Eclipse TPTP.

Если приложение Spring работает на сервере приложений (например, Tomcat), вы можете попытаться развернуть его в редакторе разработчиков tc Server (доступно в STS downloads). Он обладает интересными возможностями мониторинга.

+0

Спасибо за предложение. Я работаю над OS X, и по какой-то причине TPTP, похоже, не существует. Я забыл о tcServer, поэтому я обязательно приму этот вихрь :-) – niklassaers

+0

Обновленный URL-адрес VisualVm: https://visualvm.java.net/ – Daimon

+0

@Daimon, спасибо за обновление URL-адреса, я обновил его в ответе также –

0

Вот general discussion с рекомендованными инструментами & техники.

В принципе, вполне естественно предположить, хотите ли вы быстрее узнать, как сделать приложение, что вы должны начать с измерения того, как долго выполняются функции. Это подход сверху вниз.

Существует подход снизу вверх, когда вы думаете об этом, так же естественно. Это не вопрос о времени, а вопрос о том, что он делает, в основном, и почему он это делает.

2

Мы создали JMX & Spring AOP, основанный на @Profiled аннотации, который осуществляет мониторинг производства (активные вызовы, подсчет вызовов, время, затрачиваемое на вызовы, количество исключений и т. Д.).Показатели отображаются через JMX и могут быть собраны через Visual VM/JConsole и системами мониторинга; мы разработали плагин Hyperic HQ.

Эта аннотированная профильная версия дополнена множеством других дополнений JMX для облегчения мониторинга общих компонентов (dbcp, util.concurrent, cxf, jms и т. Д.) И предлагается по бизнес-совместимой лицензии на программное обеспечение Apache по адресу http://code.google.com/p/xebia-france/wiki/XebiaManagementExtras.

Надеется, что это помогает,

Сирил (Xebia)

0

Немного модифицированный вариант ответа Юрия на вершине (выбранный ответ), который автоматически вычисляют итоги длительностей и организует их Desc. Итоговые данные печатаются только в конце. Можете спасти вас 10 mns.

@Component 
    @Aspect 
    public class SystemArchitecture 
    { 

     @Pointcut("execution(* erp..*.*(..))") 
     public void businessController() 
     { 
     } 

     @Pointcut("execution(* TestMain..*.*(..))") 
     public void theEnd() 
     { 
     } 
    } 



    @Component 
    @Aspect 
    public class TimeExecutionProfiler 
    { 

     static Hashtable<String, Long> ht = new Hashtable<String, Long>(); 

     @Around("profiler.SystemArchitecture.businessController()") 
     public Object profile(ProceedingJoinPoint pjp) throws Throwable 
     { 
      long start = System.nanoTime(); 
      Object output = pjp.proceed(); 
      long elapsedTime = System.nanoTime() - start; 
      String methodName = pjp.getSignature().toString(); 
      if (ht.get(methodName) == null) 
      { 
       ht.put(methodName, elapsedTime); 
      } 
      else 
      { 
       ht.put(methodName, ht.get(methodName) + elapsedTime); 
      } 
      // System.out.println(methodName + " : " + elapsedTime + " milliseconds."); 

      return output; 
     } 

     @After("profiler.SystemArchitecture.theEnd()") 
     public void profileMemory() 
     { 
      List<Object> keys = Arrays.asList(ht.keySet().toArray()); 
      java.util.Collections.sort(keys, new Comparator<Object>() 
      { 

       @Override 
       public int compare(Object arg0, Object arg1) 
       { 
        return ht.get(arg1).compareTo(ht.get(arg0)); 
       } 
      }); 

      System.out.println("totals Used:"); 
      for (Object name : keys) 
      { 
       System.out.println("--" + name + " : " + (ht.get(name)/1000000)); 
      } 
      System.out.println("JVM memory in use = " + (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory())); 
     } 
    } 
Смежные вопросы