Profilage d’une application Java Spring

J’ai une application Spring qui, à mon avis, présente des goulots d’étranglement. J’aimerais donc l’exécuter avec un profileur pour mesurer les fonctions qui prennent combien de temps. Des recommandations sur la façon dont je devrais faire cela?

J’utilise STS, le projet est un projet maven et j’utilise Spring 3.0.1.

J’ai fait cela en utilisant Spring AOP.

Parfois, j’ai besoin d’informations sur le temps nécessaire à l’exécution de certaines méthodes de mon projet (la méthode du contrôleur, par exemple).

Dans servlet xml je mets

 

En outre, je dois créer la classe pour les aspects:

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

Et aspect profileur:

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

C’est tout. Lorsque je demande une page à mon application Web, les informations sur le temps d’exécution de la méthode et l’utilisation de la mémoire JVM sont imprimées dans le fichier journal de l’application Web.

Je recommande VisualVM pour le profilage général des applications. Il est disponible dans le JDK à partir de la version 1.6_10 et beaucoup plus rapide et utilisable que le TPTP d’Eclipse.

Si votre application Spring fonctionne sur un serveur d’applications (par exemple, Tomcat), vous pouvez essayer de la déployer dans l’édition de développeur tc Server (disponible dans les téléchargements STS ). Il a des capacités de surveillance intéressantes.

Vous pouvez utiliser un profileur Java open source tel que Profiler4J:

http://profiler4j.sourceforge.net/

ou Netbeans est livré avec un profileur intégré et Eclipse possède également des fonctionnalités de profilage. Cependant, j’ai trouvé Profiler4J plus facile à utiliser car il contient un joli graphique vous montrant les méthodes les plus consommasortingces de temps.

Cela fonctionne bien dans STS (éclipse), il suffit de suivre les instructions sur le site.

Nous avons développé une annotation @Profiled basée sur JMX & Spring AOP qui surveille la production (invocations actives, nombre d’appels, temps passé au cours des appels, nombre d’exceptions, etc.). Les mésortingques sont exposées via JMX et peuvent être collectées via Visual VM / JConsole et par des systèmes de surveillance. nous avons développé un plugin Hyperic HQ.

Cette annotation @profiled est fournie avec de nombreux extras JMX pour faciliter la surveillance des composants courants (dbcp, util.concurrent, cxf, jms, etc.) et proposée dans le cadre d’une licence logicielle Apache très conviviale pour les entresockets à l’ adresse http://code.google.com/. p / xebia-france / wiki / XebiaManagementExtras .

J’espère que cela t’aides,

Cyrille (Xebia)

J’ai aimé JRat , bien que, comme profiler4j, il ne semble pas être activement développé. En tout cas, c’était simple à utiliser.

Voici une discussion générale avec les outils et techniques recommandés.

Fondamentalement, il est tout à fait naturel de supposer, si vous souhaitez savoir comment créer une application plus rapidement, que vous devez commencer par mesurer la durée des fonctions. C’est une approche descendante.

Il existe une approche ascendante qui est tout aussi naturelle lorsque vous y réfléchissez. Il ne s’agit pas de demander du temps, mais de demander ce qu’il fait principalement et pourquoi il le fait.

Une version légèrement modifiée de la réponse de Yuri en haut (la réponse sélectionnée) qui calcule automatiquement les totaux des durées et les organise en desc. Les totaux sont imprimés à la fin seulement. Vous pourriez économiser 10 minutes.

  @Component @Aspect public class SystemArchitecture { @Pointcut("execution(* erp..*.*(..))") public void businessController() { } @Pointcut("execution(* TestMain..*.*(..))") public void theEnd() { } } @Component @Aspect public class TimeExecutionProfiler { static Hashtable ht = new Hashtable(); @Around("profiler.SystemArchitecture.businessController()") public Object profile(ProceedingJoinPoint pjp) throws Throwable { long start = System.nanoTime(); Object output = pjp.proceed(); long elapsedTime = System.nanoTime() - start; Ssortingng methodName = pjp.getSignature().toSsortingng(); 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 keys = Arrays.asList(ht.keySet().toArray()); java.util.Collections.sort(keys, new Comparator() { @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())); } }