JBoss Profiler: Hoe en waarom?

 
17 januari 2011

Je kent het vast wel: je applicatie is traag en je weet niet waarom. Alles zou gewoon snel moeten werken, maar er schijnt toch een soort van bottleneck te zijn. Een optie is om de hele code na te lopen om te zien of je het probleem kunt vinden, maar wie wil nu echt duizenden regels code afzoeken naar het probleem?

Het is aanzienlijk makkelijker om een profiler te gebruiken. Een profiler volgt namelijk alles wat er gebeurd en geeft een rapport terug met onder andere hoe vaak bepaalde klassen en methodes zijn aangeroepen en hoe lang het duurt voor deze uitgevoerd zijn. De uitslagen kunnen soms bijzonder verrassend zijn.

In deze blog ga ik wat meer in op de JBoss Profiler. In mijn huidige opdracht (SogyoSearch) maak ik daar namelijk gebruik van. Standaard profilers voor bijvoorbeeld Eclipse zijn lastig, of helemaal niet, te gebruiken aangezien al het verkeer via de JBoss server gaat. De JBoss Profiler is daar een oplossing voor. Deze profiler werkt namelijk op de server en is makkelijk te installeren. Er is maar weinig configuratie voor nodig en al helemaal niet in de code!

Deze blog bestaat uit drie onderdelen:

  1. Een installatie- en configuratie handleiding;
  2. Een uitleg over hoe de JBoss Profiler werkt;
  3. En een conlcusie (het nut van een profiler).

Installatie en configuratie

Deze handleiding is geschikt voor de JBoss Servers 5.x en 6.x. In de handleiding van de JBoss Profiler is ook een installatie en configuratie handleiding voor de JBoss Server 4.2 te vinden. Zelf maak ik gebruik van de JBoss Server 5.0.

Om te beginnen moet je de JBoss Profiler downloaden. Dit is een .zip of een .tar.gz bestand en kan op elk willekeurige locatie op je harde schijf uitgepakt worden. Hierin is ook de handleiding te vinden.

De volgende drie bestanden moeten naar de bin map van de JBoss Server gekopieerd worden:

  1. jboss-profiler.jar
  2. jboss-profiler.properties
  3. jboss-profiler-plugins.jar

De jboss-profiler.properties bevat vrijwel alle configuratie die nodig is voor de JBoss Profiler. Ik zal niet alles behandelen, maar de volgende regels zijn belangrijk om te weten (en om te configureren):

  • includes=nl.sogyo.sogyosearch.*
    Deze regel geeft aan wat er door de profiler in de gaten moet worden gehouden. In dit geval is dat alles binnen de nl.sogyo.sogyosearch package. Er is eventueel aan te geven of alleen de public methoden en klassen moeten worden bekeken of ook de private. Standaard staat dit op private (visibility=private).
  • excludes=*
    Hiermee is aan te geven wat er juist niet(!) bekeken moet worden. Standaard staat dit op *, dus alles wat niet in het lijstje staat bij includes.
  • save=no en startup=no
    Deze twee instellingen heb ik zelf op no gezet. Standaard staan deze namelijk op yes en dan wordt er meer gedaan dan je eigenlijk wil. Althans, meer dan dat je zelf aangeeft (hier kom ik later op terug).
  • host=localhost en port=8080
    Ik neem aan dat deze regels voor zich spreken. De port staat standaard op 5400.

Er is nog meer in te stellen, maar voor deze blog is dit voldoende. Zie de handleiding van JBoss Profiler voor meer informatie.

De volgende regel moet worden toegevoegd aan run.bat (voor Windows, run.conf voor Unix):

set JAVA_OPTS=%JAVA_OPTS% -javaagent:jboss-profiler.jar -Djboss-profiler.properties=jboss-profiler.properties

Tot slot moet de jboss-profiler.sar gekopieerd worden naar de server/<conf>/deploy map.

De JBoss Server is nu volledig geconfigureerd voor de profiler en kan gestart worden.

Hoe werkt de JBoss Profiler?

De JBoss Profiler biedt een client command prompt applicatie aan. Deze is te gebruiken vanuit de JBoss Profiler map (dus de map waar je alles in uitgepakt hebt). Met een paar commando’s is het mogelijk om de profiler te starten, stoppen en om een snapshot aan te maken. Er zijn meer opties, maar deze drie zijn het belangrijkste (zie de handleiding voor meer informatie over de andere mogelijkheden).

Er zijn een paar kleine configuraties nodig om alles werkend te krijgen:

  • jboss-profiler.properties
    Dit bestand is hetzelfde als het bestand in de bin map van de JBoss Server. Deze is dus 1 op 1 over te nemen.
  • jboss-profiler-client.properties
    Dit bestand hoeft niet aangepast te worden. Sterker nog, je krijgt errors als je het wel aanpast. Ondanks dat de configuratie die erin staat totaal onlogisch lijkt (protocol is socket en port 5400), moet alles blijven staan zoals het staat!

Ook de JBoss Profiler is nu klaar voor gebruik. Als het goed is, is tegen deze tijd de JBoss Server opgestart. De profiler maakt connectie met de server, dus zorg ervoor dat deze aanstaat (anders wordt je hardhandig duidelijk gemaakt dat je de server aan moet zetten ;-)).

Open de command prompt en ga naar de JBoss Profiler map (die je in het begin hebt uitgepakt). Bij mij is dit C:\jboss-profiler-2.0.0.Beta5. Vanaf hier is de client van de profiler aan te roepen. De volgende regel start de JBoss Profiler:

java -Xmx512m -Djboss-profiler-client.properties=jboss-profiler-client.properties -jar jboss-profiler-client.jar startProfiler

Vanaf nu is de profiler aan het luisteren. Alles wat er gebeurd, wordt vastgelegd door de profiler. Belangrijk is wel dat er genoeg geheugen moet zijn! Ik heb geprobeerd het indexeren van SogyoSearch te profilen, maar kreeg steeds een OutOfMemoryException. Maar dat is dan ook een erg zware actie.

Wanneer je klaar bent met profilen, kan je de profiler stoppen met de volgende regel:

java -Xmx512m -Djboss-profiler-client.properties=jboss-profiler-client.properties -jar jboss-profiler-client.jar stopProfiler

De oplettende lezers hebben het vast al gezien: het enige verschil is het laatste woord (stopProfiler). Vervolgens kan er een snapshot gemaakt worden:

java -Xmx512m -Djboss-profiler-client.properties=jboss-profiler-client.properties -jar jboss-profiler-client.jar snapshot

Deze snapshot bevat alle informatie die de profiler heeft verzameld en wordt opgeslagen in dezelfde map als de JBoss Profiler. De snapshot bevat een index.html:

index.html

index.html

Er zijn verschillende onderdelen te vinden, maar ik zal me beperken tot de Overview aangezien daar vrijwel alles te vinden is. Er is onder andere te vinden wat de tijden zijn waarop de profiler bezig was en wat de belangrijkste knelpunten (Most time en Hotspots) zijn. Bij beide onderdelen is te zien hoe vaak een methode aangeroepen is (Count), hoeveel ms het in totaal koste, wat de gemiddelde tijd is en hoeveel procent dit van het geheel is.

Dit overzicht geeft dus aan wat en nu precies langzaam is. De volgende methode wordt bijvoorbeeld maar 1x aangeroepen, maar is wel onnoemlijk langzaam (klik op de afbeelding om deze te vergroten):

Langzame methode (link)

Langzame methode

Het blijkt zelfs ruim 44% van het geheel te zijn! Er is dus bij het refactoren van deze methode mogelijk veel winst te halen.

Maar dit is niet alles wat met de profiler gevonden kan worden. Er kunnen ook problemen in de structuur van de applicatie gevonden worden. Neem bijvoorbeeld het volgende resultaat:

Probleem in de structuur van de applicatie

Probleem in de structuur van de applicatie

Op het eerste gezicht is er niet veel te zien. De methodes worden 10x aangeroepen en is ook nog eens relatief snel. Geen probleem zou je zeggen. Maar het wordt wel een probleem wanneer je bedenkt dat deze methodes aangeroepen worden vanuit een Singleton (en ja, ik heb de vorige discussie ook gelezen. Sterker nog: ik heb eraan meegedaan, dus mocht je opmerkingen hebben over waarom het een Singleton is… Stel die niet hier ;-))! Het is dus onmogelijk dat deze methodes 10x worden aangeroepen. Althans, dat zou onmogelijk moeten zijn! Reden genoeg dus om hier eens goed naar te kijken.

Belangrijk is echter wel om te weten dat een methode misschien wel erg vaak wordt aangeroepen, maar dat dit niet altijd erg hoeft te zijn. Ook kan het zo zijn dat een methode lang duurt, maar dat dit ook kan komen omdat deze methode misschien gebruik maakt van een IO bewerking (zoals het lezen van de harde schijf):

Langzame methode

Langzame methode

Deze methode duurt lang, maar er wordt wel naar een bestand op de harde schijf geschreven. Het kan zijn dat dit niet sneller te maken is. De volgende methode wordt veruit het vaakst aangeroepen. Maar het is tevens de snelste die er is!

Veel gebruikte methode

Veel gebruikte methode

Deze methode wordt voor elk woord aangeroepen dat wordt geïndexeerd en is dus niet efficiënter te maken. Het is daarnaast een methode van Lucene zelf.

Conclusie: Het nut van een profiler?

Het gebruik van een profiler kan dus grote voordelen hebben. Zo hoef je niet meer zelf alle code langs te gaan om het probleem ‘mogelijk’ te kunnen vinden, je code kan er beter door worden en de applicatie kan aanzienlijk sneller worden. Wel is het belangrijk om goed te kijken of het wel een probleem is, of dat het gewoon komt omdat er gebruik gemaakt wordt van langzame bronnen als de harde schijf (IO). Ook is het niet altijd erg als een methode tig keer wordt aangeroepen. Zolang er maar een goede reden voor is!

Kortom, gebruik zo af en toe eens een profiler om te kijken waar verbeteringen plaats kunnen vinden. De code zal er beter door worden!


Werken met ?
Kijk dan bij onze mogelijkheden voor zowel starters als ervaren engineers.


Categorieën: Architectuur, Development, Java (EE), Open Source

Tags: , , , , , ,