Профилирование приложения Java Spring
У меня есть приложение Spring, которое, как я считаю, имеет некоторые узкие места, поэтому я хотел бы запустить его с профилировщиком, чтобы определить, какие функции занимают сколько времени. Любые рекомендации, как я должен это делать?
Я запускаю STS, проект - проект maven, и я запускаю Spring 3.0.1
Ответы
Ответ 1
Я сделал это с помощью 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.
Ответ 2
Я рекомендую VisualVM для общего профилирования приложений. Он доступен в JDK версии 1.6_10, а imho - намного быстрее и удобнее, чем Eclipse TPTP.
Если ваше приложение Spring работает на сервере приложений (например, Tomcat), вы можете попытаться развернуть его в редакторе разработчиков tc Server (доступно в Загрузка STS). Он имеет интересные возможности мониторинга.
Ответ 3
Вы можете использовать профилировщик java с открытым исходным кодом, например Profiler4J:
http://profiler4j.sourceforge.net/
или Netbeans поставляется со встроенным профилировщиком, и Eclipse также имеет возможности профилирования, однако я нашел, что Profiler4J проще в использовании, поскольку у него есть хороший график, показывающий вам наиболее трудоемкие методы.
Это хорошо работает в STS (eclipse), просто следуйте инструкциям на сайте.
Ответ 4
Мы разработали JMX и Spring AOP, основанную на @Profiled аннотации, которая осуществляет мониторинг производства (активные вызовы, подсчет вызовов, время, затраченное на вызовы, количество исключений и т.д.). Показатели отображаются через JMX и могут быть собраны через Visual VM/JConsole и системами мониторинга; мы разработали плагин Hyperic HQ.
Эта аннотация @profiled упакована со многими другими дополнительными функциями JMX для облегчения мониторинга общих компонентов (dbcp, util.concurrent, cxf, jms и т.д.) и предлагается в соответствии с бизнес-совместимой лицензией на программное обеспечение Apache по адресу http://code.google.com/p/xebia-france/wiki/XebiaManagementExtras.
Надеюсь, что это поможет,
Кирилл (Xebia)
Ответ 5
Мне понравился JRat, хотя, как и у profiler4j, он, похоже, не активно развивается. В любом случае это было простое использование.
Ответ 6
Здесь общая дискуссия с рекомендуемыми инструментами и методами.
В принципе, вполне естественно предположить, хотите ли вы быстрее узнать, как сделать приложение, и начать с него, измеряя, как долго выполняются функции.
Это подход сверху вниз.
Там подход снизу вверх, когда вы думаете об этом, так же естественно. Это не вопрос о времени, а вопрос о том, что он делает, в основном, и почему он это делает.
Ответ 7
Немного измененная версия ответа Yuri сверху (выбранный ответ), который автоматически вычисляет итоговые значения продолжительности и упорядочивает их desc. Итоговые данные печатаются только в конце.
Мог бы спасти вас 10 мн.
@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()));
}
}