分析 Java Spring 应用程序
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2475682/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Profiling a Java Spring application
提问by niklassaers
I have a Spring application that I believe has some bottlenecks, so I'd like to run it with a profiler to measure what functions take how much time. Any recommendations to how I should do that?
我有一个 Spring 应用程序,我认为它有一些瓶颈,所以我想用分析器运行它来测量哪些函数需要多少时间。关于我应该如何做的任何建议?
I'm running STS, the project is a maven project, and I'm running Spring 3.0.1
我正在运行STS,该项目是一个maven项目,我正在运行Spring 3.0.1
采纳答案by Yuri.Bulkin
I've done this using Spring AOP.
我已经使用 Spring AOP 完成了这项工作。
Sometime I need an information about how much time does it take to execute some methods in my project (Controller's method in example).
有时我需要有关在我的项目中执行某些方法需要多长时间的信息(例如 Controller 的方法)。
In servlet xml I put
在servlet xml中我放
<aop:aspectj-autoproxy/>
Also, I need to create the class for aspects:
另外,我需要为方面创建类:
@Component
@Aspect
public class SystemArchitecture {
@Pointcut("execution(* org.mywebapp.controller..*.*(..))")
public void businessController() {
}
}
And profiler aspect:
和分析器方面:
@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()));
}
}
That's all. When I request a page from my webapp, the information about method executing time and JVM memory usage prints out in my webapp's log file.
就这样。当我从我的 webapp 请求一个页面时,有关方法执行时间和 JVM 内存使用情况的信息会打印在我的 webapp 的日志文件中。
回答by Neal Donnan
You can use an open source java profiler such as Profiler4J:
您可以使用开源 Java 分析器,例如 Profiler4J:
http://profiler4j.sourceforge.net/
http://profiler4j.sourceforge.net/
or Netbeans comes with a built in profiler and Eclipse also has profiling capabilities, however I found Profiler4J easier to use since it has a nice graph showing you the most time consuming methods.
或者 Netbeans 带有一个内置的分析器,Eclipse 也有分析功能,但是我发现 Profiler4J 更容易使用,因为它有一个很好的图表向您展示最耗时的方法。
This works well in STS (eclipse), just follow the instructions on the site.
这在 STS (eclipse) 中运行良好,只需按照网站上的说明进行操作即可。
回答by laura
回答by Csaba_H
I recommend VisualVMfor general application profiling. It is available in the JDK from version 1.6_10, and imho much faster and usable than Eclipse TPTP.
我推荐VisualVM用于一般应用程序分析。它在 1.6_10 版的 JDK 中可用,恕我直言,它比 Eclipse TPTP 更快且可用。
(If your Spring application works in an application server (e.g. Tomcat) you could try to deploy it to the tc Server developer edition (available in the STS downloads). It has interesting monitoring capabilities.It seems that tc Server developer edition is not maintained anymore.)
(如果你的Spring应用是在应用服务器(例如Tomcat)上运行的,你可以尝试部署到tc Server开发版(在STS下载中可以找到)。它有有趣的监控功能。看来tc Server开发版没有维护没有了。)
UPDATE 2019.02.22.: updated VisualVM url (thanks for @Jeff) and tc Server information. Personally I currently use Glowrootfor monitoring Spring applications running in an application server.
更新 2019.02.22。:更新了 VisualVM url(感谢@Jeff)和 tc 服务器信息。我个人目前使用Glowroot来监控在应用服务器中运行的 Spring 应用程序。
回答by Mike Dunlavey
Here's a general discussionwith recommended tools & techniques.
这是对推荐工具和技术的一般性讨论。
Basically, it is entirely natural to assume if you want to find out how to make an app faster, that you should start by measuring how long functions take. That's a top-down approach.
基本上,很自然地假设,如果您想找出如何更快地制作应用程序,您应该从测量功能需要多长时间开始。这是一种自上而下的方法。
There's a bottom-up approach that when you think about it is just as natural. That is not to ask about time, but to ask what it is doing, predominantly, and why it is doing it.
有一种自下而上的方法,当您考虑它时同样自然。这不是问时间,而是问它主要在做什么,以及它为什么这样做。
回答by Cyrille Le Clerc
We developed a JMX & Spring AOP based @Profiled annotation which does production monitoring (active invocations, invocations count, time spent during invocations, exceptions count, etc) . Metrics are exposed via JMX and can be collected via Visual VM / JConsole and by monitoring systems ; we developed an Hyperic HQ Plugin.
我们开发了一个基于 JMX 和 Spring AOP 的 @Profiled 注释,它进行生产监控(活动调用、调用计数、调用期间花费的时间、异常计数等)。指标通过 JMX 公开,可以通过 Visual VM/JConsole 和监控系统收集;我们开发了一个 Hyperic HQ 插件。
This @profiled annotation is packaged with many other JMX extras to ease monitoring of common components (dbcp, util.concurrent, cxf, jms, etc) and proposed under a business friendly Apache Software License at http://code.google.com/p/xebia-france/wiki/XebiaManagementExtras.
这个@profiled 注释与许多其他 JMX 附加功能打包在一起,以简化对常见组件(dbcp、util.concurrent、cxf、jms 等)的监控,并在http://code.google.com/ 上的商业友好 Apache 软件许可证下提出p/xebia-france/wiki/XebiaManagementExtras。
Hope this helps,
希望这可以帮助,
Cyrille (Xebia)
西里尔 (Xebia)
回答by AhHatem
A bit modified version of Yuri's answer on top (the selected answer) that auto calculates the totals of durations and arranges them desc. The totals gets printed in the end only. Might save you 10 mns.
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()));
}
}
回答by Shmarkus
You could always use Java Mission Controls Flight Recorder that is bundled with Java, to profile your code execution
您始终可以使用与 Java 捆绑的 Java Mission Controls Flight Recorder 来分析您的代码执行情况