分析Java Spring应用程序

时间:2010-03-19 07:43:35

标签: java spring profiling

我有一个Spring应用程序,我认为它有一些瓶颈,所以我想用一个分析器来运行它来测量哪些函数花了多少时间。对我应该如何做的任何建议?

我正在运行STS,该项目是一个maven项目,我正在运行Spring 3.0.1

8 个答案:

答案 0 :(得分:17)

我使用Spring AOP完成了这项工作。

有时我需要一个关于在我的项目中执行某些方法需要多长时间的信息(例子中的Controller方法)。

在servlet xml中我放了

<aop:aspectj-autoproxy/>

另外,我需要为方面创建类:

@Component
@Aspect
public class SystemArchitecture {

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

and profiler方面:

@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日志文件中。

答案 1 :(得分:4)

我建议VisualVM进行常规应用程序分析。它可以在版本1.6_10的JDK中使用,并且比Eclipse TPTP快得多且可用。

如果您的Spring应用程序在应用程序服务器(例如Tomcat)中运行,您可以尝试将其部署到tc Server开发人员版本(在STS downloads中提供)。它具有有趣的监视功能。 / em>似乎不再维护tc Server开发人员版本了。)

更新2019.02.22。:更新了VisualVM网址(感谢@Jeff)和tc服务器信息。就个人而言,我目前使用Glowroot来监视在应用程序服务器中运行的Spring应用程序。

答案 2 :(得分:2)

您可以使用开源Java分析器,例如Profiler4J:

http://profiler4j.sourceforge.net/

或Netbeans附带内置的分析器,Eclipse也具有分析功能,但是我发现Profiler4J更容易使用,因为它有一个很好的图表显示最耗时的方法。

这在STS(eclipse)中效果很好,只需按照网站上的说明进行操作。

答案 3 :(得分:2)

我们开发了JMX&amp;基于Spring AOP的@Profiled注释,用于执行生产监控(活动调用,调用计数,调用期​​间花费的时间,异常计数等)。度量标准通过JMX公开,可以通过Visual VM / JConsole和监控系统收集;我们开发了Hyperic HQ插件。

这个@profiled注释与许多其他JMX附加组件一起打包,以便于监视常见组件(dbcp,util.concurrent,cxf,jms等),并在http://code.google.com/p/xebia-france/wiki/XebiaManagementExtras的商业友好Apache软件许可下提出。< / p>

希望这有帮助,

Cyrille(Xebia)

答案 4 :(得分:1)

我喜欢JRat,虽然像profiler4j似乎没有积极开发。无论如何,使用起来很简单。

答案 5 :(得分:0)

这是general discussion推荐工具&amp;技术。

基本上,如果您想了解如何更快地制作应用程序,那么您应该首先考虑功能需要多长时间。 这是一种自上而下的方法。

有一种自下而上的方法,当你想到它同样自然。这不是询问时间,而是询问它主要是做什么,以及它为什么这样做。

答案 6 :(得分:0)

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()));
        }
    }

答案 7 :(得分:0)

您始终可以使用与Java捆绑在一起的Java Mission Controls Flight Recorder来分析代码执行情况