Java Memory Leaks zur Laufzeit ermitteln – Nachtrag

Keine Kommentare

In Akt 5 unserer OutOfMemoryError Tragödie, sprach ich darüber, dass es leider keine freien Tools zur Laufzeit Speicheranalyse gibt. Da ich ein kommerzielles Tool besprochen hab, habe ich direkt negatives Feedback erhalten 🙁
Kurz nachdem ich den Beitrag veröffentlich hatte wurde ich auf ein Produkt namens „plumbr“ aufmerksam gemacht. Plumbr ist aktuell in der Betaphase. Das heißt, es ist aktuell kostenlos erhältlich, und ihre Macher haben sogar öffentlich zur Diskussion eines Preises aufgerufen. Trotzdem müssen wir akzeptieren, dass es keine kostenlose Lösung gibt. Das ist nicht meine Schuld, also seid mir nicht deshalb böse 🙂

In diesem kurzen Update zeige ich wie plumbr das gleiche Leak, welches ich bereits mit AppDynamics gezeigt hab, findet.

Installation

Plumbr ist genauso einfach zu installieren wie AppDynamics. Das Downloadpaket enthält Dateien für verschiedene Platformen, also ist direkt klar, dass es sich um einen JVMTI native Agenten in Kombination mit einem Javaagenten handelt. Nach dem Entpacken muss ich nur folgende Zeilen in die catalina.bat meines Tomcat 7 schreiben um den Agenten zu aktivieren:

SET PATH=C:\Tools\plumbr\plumbr\win\64;%PATH%
set CATALINA_OPTS=-agentlib:plumbr -javaagent:C:\Tools\plumbr\plumbr\plumbr.jar

Memory Leaks Schnell Entdeckt

Plumbr arbeitet sehr schnell! Ich deployte meine leakende Anwendung und startete mein Lastskript. Und schon nach wenigen Minuten erschien diese Meldung:

Also musste ich nur noch den generierten Bericht öffnen:

Tadaa! Das Leak wurde korrekt identifiziert. Auch wird uns die wichtigste Information geliefert, nämlich wo das Leak eigentlich herkommt:

The objects are created at
  de.codecentric.memleak.leak.StringQueueLeak.leak(de.codecentric.memleak.domain.Bookmark):58

Vergleichen wir diese Information mit AppDynamics, so liefert plumber etwas kürzere Call Stacks. Auch fehlen die Aufrufzahlen, dennoch ist dies genau die Information die wir benötigen um das Leak zu identifizieren und zu beheben. Bonus: Es ist super simpel dargestellt.

Weitere Verbesserungen

Interessanterweise findet Plumbr 3 Leaks, während AppDynamics nur eines fand. Das zweite und dritte sind Objekte der Derby Datenbank:

Plumbr geht also aktuell davon aus, dass Referenzes aus dem java.lang.ref.Finalizer ein Memory Leak sind. Es gibt in der Tat einige Kontroversen darüber ob es sich wirklich um Memory Leaks handelt (z.b. in dieser Diskussion auf stackoverflow). Ich habe diese Beobachtung an das plumber Entwicklerteam geschickt und kurz darauf Antwort erhalten: Zwar gehen sie davon aus, dass Finalizer ein Problem sind, jedoch wollen sie in der nächsten Version die Handhabung verändern um false positives zu reduzieren.

Ich denke plumbr ist eine wirklcih interessante Lösung. Es löst ein sehr spezifisches Problem auf elegante Art und Weise. Es ist schnell und konnte in meiner Testanwendung keinen spürbaren overhead erzeugen. Allerdings muss ich noch Tests in echten Anwendungen durchführen.

Fabian Lange ist Lead Agent Engineer bei Instana und bei der codecentric als Performance Geek bekannt. Er baut leidenschaftlich gerne schnelle Software und hilft anderen dabei, das Gleiche zu tun.
Er kennt die Java Virtual Machine bis in die letzte Ecke und beherrscht verschiedenste Tools, die JVM, den JIT oder den GC zu verstehen.
Er ist beliebter Vortragender auf zahlreichen Konferenzen und wurde unter anderem mit dem JavaOne Rockstar Award ausgezeichnet.

Share on FacebookGoogle+Share on LinkedInTweet about this on TwitterShare on RedditDigg thisShare on StumbleUpon

Kommentieren

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.