我有一个Spring应用程序,我认为它存在一些瓶颈,所以我想使用性能分析器来测量每个函数执行的时间。你有什么推荐的方法吗?
我正在运行STS,这个项目是一个Maven项目,使用的是Spring 3.0.1。
我使用了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()));
}
}
就这些了。当我从我的 Web 应用程序请求页面时,有关方法执行时间和 JVM 内存使用情况的信息会打印到我的 Web 应用程序日志文件中。
这里有一个通用讨论,介绍了推荐的工具和技术。
基本上,如果您想要了解如何使应用程序更快,那么假设您应该从测量函数花费的时间开始是完全自然的。这是一种自上而下的方法。
还有一种自下而上的方法,在考虑它时同样自然。这不是问时间,而是问主要做什么,以及为什么要这样做。
@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()));
}
}
我喜欢 JRat,虽然像 profiler4j 一样,它似乎没有在积极开发。无论如何,它很容易使用。