【发布时间】:2011-01-29 08:39:46
【问题描述】:
我有一个 Spring 应用程序,我认为它存在一些瓶颈,因此我想使用分析器来运行它以测量哪些功能需要多少时间。对我应该如何做有什么建议吗?
我正在运行 STS,该项目是一个 maven 项目,我正在运行 Spring 3.0.1
【问题讨论】:
-
分析 Spring 应用程序与分析任何其他 java 应用程序并没有什么不同。您可能希望扩大问题范围,以获得更广泛的答案选择。
我有一个 Spring 应用程序,我认为它存在一些瓶颈,因此我想使用分析器来运行它以测量哪些功能需要多少时间。对我应该如何做有什么建议吗?
我正在运行 STS,该项目是一个 maven 项目,我正在运行 Spring 3.0.1
【问题讨论】:
您始终可以使用与 Java 捆绑在一起的 Java Mission Controls Flight Recorder 来分析您的代码执行情况
【讨论】:
我推荐VisualVM 用于一般应用程序分析。它在 JDK 1.6_10 版本中可用,并且比 Eclipse TPTP 更快且可用。
(如果您的 Spring 应用程序在应用程序服务器(例如 Tomcat)中工作,您可以尝试将其部署到 tc Server 开发人员版本(在 STS downloads 中提供)。它具有有趣的监控功能。 tc Server 开发者版好像没有维护了。)
UPDATE 2019.02.22.:更新了 VisualVM url(感谢 @Jeff)和 tc 服务器信息。我个人目前使用Glowroot 来监控在应用服务器中运行的Spring 应用程序。
【讨论】:
顶部的 Yuri 答案(所选答案)的稍微修改版本,它会自动计算持续时间的总数并按顺序排列。总数仅在最后打印。 可能会为您节省 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()));
}
}
【讨论】:
我们开发了一个基于 JMX 和 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 软件许可下提出。
希望这会有所帮助,
西里尔 (Xebia)
【讨论】:
这是一个general discussion,其中包含推荐的工具和技术。
基本上,如果您想了解如何让应用程序变得更快,您会很自然地假设您应该从测量函数需要多长时间开始。 这是一种自上而下的方法。
有一种自下而上的方法,当您考虑它时,它同样自然。这不是询问时间,而是询问它主要在做什么,以及为什么这样做。
【讨论】:
我喜欢JRat,尽管它和 profiler4j 一样似乎没有被积极开发。无论如何,它使用起来很简单。
【讨论】:
我已经使用 Spring AOP 完成了这项工作。
有时我需要有关在我的项目中执行某些方法(例如控制器的方法)需要多少时间的信息。
在 servlet 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 的日志文件中。
【讨论】:
您可以使用开源的 java profiler,例如 Profiler4J:
http://profiler4j.sourceforge.net/
或者 Netbeans 带有内置的分析器,而 Eclipse 也具有分析功能,但是我发现 Profiler4J 更易于使用,因为它有一个漂亮的图表,可以向您展示最耗时的方法。
这在 STS (eclipse) 中运行良好,只需按照网站上的说明进行操作即可。
【讨论】: