Профилирование приложения Java Spring - PullRequest
15 голосов
/ 19 марта 2010

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

Я использую STS, проект maven, а я запускаю Spring 3.0.1

Ответы [ 8 ]

17 голосов
/ 19 марта 2010

Я сделал это с помощью Spring AOP.

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

В сервлете 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()));
    }
}

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

4 голосов
/ 19 марта 2010

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

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

ОБНОВЛЕНИЕ 2019.02.22. : обновлены URL-адрес VisualVM (спасибо за @Jeff) и информация о сервере tc. Лично я в настоящее время использую Glowroot для мониторинга приложений Spring, работающих на сервере приложений.

2 голосов
/ 02 февраля 2011

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

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

Надеюсь, это поможет,

Сирил (Ксебия)

2 голосов
/ 19 марта 2010

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

http://profiler4j.sourceforge.net/

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

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

1 голос
/ 19 марта 2010

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

0 голосов
/ 25 марта 2019

Вы всегда можете использовать Java Mission Controls Flight Recorder, который поставляется в комплекте с Java, для профилирования выполнения кода

0 голосов
/ 15 января 2012

Немного измененная версия ответа Юрия сверху (выбранный ответ), который автоматически вычисляет итоги длительностей и упорядочивает их. Итоги печатаются только в конце. Может сэкономить 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()));
        }
    }
0 голосов
/ 19 марта 2010

Вот общее обсуждение с рекомендуемыми инструментами и методами.

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...