Category: Java

  • How to create Memory Leaks by using Inner Classes.

    The most recent Java Specialists Newsletter finally convinced me to start this post that I was having in mind for quite some time.

    One of the really huge advantages of Java is that you almost do not have to care about cleaning up your memory as the Garbage Collector usually does this for you as soon as Objects are no more referenced. Usually this works really really well so that you really don’t have to care about annything! But maybe once in a while you may be observing something like a memory leak. Some people then call the Garbage explicitly – which is usually just a bad idea and possibly also doesn’t help either so that the “leak” remains. The better solution in this case would be profiling so that you can see why some classes are not cleaned up.

    A nice source for memory leaks can be the use of anonymous inner classes. Assume the following class where you want to compute s.th and return a Result-Object which derives from an Interface:

    interface Result{}
    class Outer {
        int[] data = null;
        public Outer(int s) { data = new int[s]; }
        Object getResult() { return new Result(){}; }
    }

    So if you call new Outer(1).getResult(), you will still have an instance of Outer in memory even though you did not keep an explicit reference. As explained in the Java Specialists Newsletter, each instance of an anoymous inner class always keeps a reference to the outer class! This is not a big deal as long as

    • you don’t keep a lot of data in the Outer instance or
    • if the lifetime of the Result object is not long or
    • if you won’t create a lot of results anyways.

    Let’s have an example. If you execute

    ArrayList l = new ArrayList();
    int i = 0;
    while(true){
        l.add(new Outer(0).getResult());
        System.out.println(i++);
    }

    with the above classes without memory constraints (-Xmx), this will run for quite some time because you are only holding 2 class references (Outer, Result) 1 field (the emtpty data array) and an implicit reference from Result to Outer. Which makes a total of 48 bytes on my Win7 64bit machine (according to this measurement).

    Now change the parameter in the constructor of Outer from 0 to 100000 and execute the code again. In my case I am getting an OutOfMemoryException after a bit more than 2000 created instances as now suddenly each iteration consumes 400.048 bytes (48 bytes as before + 100.000*4 bytes for the int-array) even though we only keep the explicit reference to the Result objects!

    So – if you are creating an inner class the next time – you might have a brief look at the outer class as well and think about memory consumption and lifetime.

  • MARiO: Multi Attribute Routing in Open Street Map

    Yeah, I got a new Publication accepted at Symposium on Spatial and Temporal Databases (SSTD) 2011 that is dealing with OpenStreetMap Data (using the JXMapKit and JXMapViewer).

    MARiO: Multi Attribute Routing in Open Street Map

    Franz Graf, Hans-Peter Kriegel, Matthias Schubert, Matthias Renz

    Published at Symposium on Spatial and Temporal Databases (SSTD) 2011
    Conference Date: August 24th – 26th, 2011
    Conference Location: Minneapolis, MN, USA.

    Abstract:

    In recent years, the Open Street Map (OSM) project collected a large repository of spatial network data containing a rich variety of information about traffic lights, road types, points of interest etc.. Formally, this network can be described as a multi-attribute graph, i.e. a graph considering multiple attributes when describing the traversal of an edge. In this demo, we present our framework for Multi Attribute Routing in Open Street Map (MARiO). MARiO includes methods for preprocessing OSM data by deriving attribute information and integrating additional data from external sources. There are several routing algorithms already available and additional methods can be easily added by using a plugin mechanism. Since routing in a multi-attribute environment often results in large sets of potentially interesting routes, our graphical fronted allows various views to interactively explore query results.

    Documents:

    Bibtex

    @INPROCEEDINGS{GraKriRenSch11,
      AUTHOR      = {F. Graf and H.-P. Kriegel and M. Renz and M. Schubert},
      TITLE       = {{MARiO}: Multi Attribute Routing in Open Street Map},
      BOOKTITLE   = {Proceedings of the 12th International Symposium on Spatial and Temporal Databases (SSTD), Minneapolis, MN, USA},
      YEAR        = {2011}
    }
  • Performanceanalyse mit JVisualVM – evil synchronized

    In einem meiner kleinen Projekte werden an einer Stelle etliche Threads gestartet, die jeweils ein Bild einlesen, skalieren und wieder auf die Platte schreiben. – Die ganze Zeit hat mich schon das Gefühl beschlichen, dass das zu langsam läuft, untersucht hatte ich das bisher nur nie. Nachdem genau diese Funktionalität heute definitv zu langsam war, kam ich um eine Analyse wohl doch nicht mehr herum. Also erst mal untersuchen, was da vor sich geht:

    • Programm gestartet,
    • JVisualVM gestartet (zu finden im bin-Verzeichnis einer JDK-Installation),
    • VisualVM auf das laufende Programm verbunden, und die Threads anzeigen lassen
    • kritische Funktion im Programm gestartet

    Und siehe da: die Threads werden gestartet, aber nur immer genau einer ausgeführt (siehe Bild). Alle anderen Threads die laufen sollten stehen auf “Monitor”. Das ist leicht daran zu erkennen, dass zwar alle PictureScaleWorker ausgeführt werden, aber niemals gleichzeitig alle grün (also im Running State) sind sondern immer nur einer. Na das sollte ja nicht so sein!

    Aber was machen die eigentlich und worauf warten die? Also erst mal einen Thread Dump erstellen (Button oben rechts), vielleicht bringt der ja ein paar Infos:

    Dann zu einem der betreffenden Threads scrollen und nachsehen, ob dort etwas auffällig ist.

    Thread.State: BLOCKED (on object monitor)
    at de.locked.gallery.utils.ImageUtils.read (ImageUtils.java:83)

    Blocked on object monitor – das sieht nach einem synchronized aus. Und betreffende Zeile 83 ist tatsächlich synchronized – was ich bei einem der letzten Refactorings offenbar übersehen habe. Mittlerweile ist die Synchronisierung auf dieser Methode zum Glück nicht mehr nötig und ich kann die Einschränkung ohne Gewissenbisse entfernen. Und siehe da, auf einmal laufen auch alle Threads gleichzeitig, was auf 8 Kernen doch einen spürbaren Unterschied macht. – Willkommen im Multi-Core Zeitalter.

    Ohne die JVisualVM wäre ich früher oder später wohl auch an die Stelle gekommen – aber ich bezweifle ernsthaft dass ich die Stelle innerhalb weniger Minuten gefunden hätte.

    Dazu auch ein interessantes Video.

  • Selektionsfenster in SwingX-WS / JXMapKit

    Um in der Mapkomponente von JXMapKit eine Selektion (Rechteck mit Rahmen und leicht transparenter Füllung) zu zeichnen, wird lediglich ein entsprechender Painter und ein Mouseadapter benötigt. Der Code dazu sieht folgendermaßen aus:

    Der Painter & MouseListener:

    public class SelectionPainter extends MouseAdapter implements Painter<JXMapViewer> {
    
        private Rectangle rect, start, end;
        private Color borderColor = new Color(0, 0, 200);
        private Color regionColor = new Color(0, 0, 200, 75);
    
        public SelectionPainter() {
        }
    
        @Override
        public void mousePressed(MouseEvent e) {
            if (e.getButton() != MouseEvent.BUTTON1) {
                rect = null;
                start = null;
            } else {
                start = new Rectangle(e.getPoint());
                ((JXMapViewer) e.getSource()).setPanEnabled(false);
            }
        }
    
        @Override
        public void mouseDragged(MouseEvent e) {
            if (start != null) {
                end = new Rectangle(e.getPoint());
                rect = start.union(end);
            }
            ((JXMapViewer) e.getSource()).repaint();
        }
    
        @Override
        public void mouseReleased(MouseEvent e) {
            if (start == null) {
                return;
            }
            end = new Rectangle(e.getPoint());
            rect = start.union(end);
            ((JXMapViewer) e.getSource()).setPanEnabled(true);
            ((JXMapViewer) e.getSource()).repaint();
        }
    
        @Override
        public void paint(Graphics2D gd, JXMapViewer t, int i, int i1) {
            if (rect != null) {
                gd.setColor(regionColor);
                gd.fillRect(rect.x, rect.y, rect.width, rect.height);
                gd.setColor(borderColor);
                gd.drawRect(rect.x, rect.y, rect.width, rect.height);
            }
        }
    }

    Verbindung zur Map-Komponente:

     SelectionPainter sp = new SelectionPainter();
    mapKit.getMainMap().addMouseListener(sp);
    mapKit.getMainMap().addMouseMotionListener(sp);
    mapKit.getMainMap().setOverlayPainter(sp);

    mapKit ist dabei eine Instanz von org.jdesktop.swingx.JXMapKit.

    Artikel mit gepatchtem SwingX-WS

  • PAROS download!

    Das Ziel war nobel: Code aufräumen, schöner machen, refactoren und dokumentieren und dann online stellen.

    Die Realität war derart, dass es leider wichtigeres zu tun gibt. Daher stelle ich das PAROS-Projekt, das dieses Jahr auf der SIGMOD war so online wie es ist: lauffähig, und vom Softwareengineeringaspekt ziemlich hässlich. Aber vielleicht kann ja jemand etwas damit anfangen – zumindest die kleinen hacks um größere Graphen auch annehmbar schnell zeichnen zu können.

    Ausserdem ist es ein schönes Beispiel, wie man JXMapKit und OpenStreetMap (OSM) zu Forschungszwecken im Bereich Datamining, GIS (GeoInformationssysteme) und auch SpatialIndexing  verwenden kann. Auf der Konferenz kannten viele OSM nämlich erstaunlicherweise gar nicht, obwohl sie auf dem Bereich tätig waren.

    Und zur nächsten Version muss ich nochmal nachsehen, ob es nach den Google Maps Terms of Services  immernoch verboten ist, Maps in Nicht-Browser-Anwendungen zu integrieren. Wäre natürlich auch sehr nett, oder weiß jemand Bescheid? (Update Jan. 2011: das ist nicht mehr verboten!)

    Relevante Links:

  • JavaBeans via GUI konfigurieren

    Was genau Java Beans isnd und wozu sie konzipiert sind, möchte ich an dieser Stelle nicht komplett und genau ausführen, dazu gibt es schon genügend Literatur (siehe Linkliste unten). Stattdessen möchte ich nur ganz grob das Konzept umreißen, darstellen wozu man Beans (unter anderem) benutzen kann und dann eine kleine Bean-Konfig-GUI zeigen, die mich mehr Zeit gekostet hat, als ich erst dachte …

    Was sind Java Beans?

    Eine Java Bean ist eine Klasse, die mindestens die folgenden Eigenschaften erfüllt:

    • öffentlicher Standardkonstruktor
    • öffentliche Zugriffsmethoden (also getter/setter für die relevanten Attribute)
    • Serialisierbarkeit (für das folgende Beispiel nicht wichtig)

    Nicht viel also. Beispiele sind übrigens alle UI-Klassen von Swing, also zB JButton, JLabel, etc. Tonnenweise zugehörige Literatur kann man sich an einem ruhigen Winterabend gerne zu Gemüte führen

    Wozu sind JavaBeans?

    Beans kommen in vielen Java-Bereichen vor: GUIs, Servlets, Persitenz, etc. Java Beans bieten die Möglichkeit von außen per Introspection ausgelesen und bearbeitet zu werden, sie enthalten Attribute (Properties), die den Zustand beschreiben, sie können Events auslösen, sie bieten die Möglichkeit der Persistenz und sie können per Customization angepasst werden. Der letzte Punkt ist zugegebenermaßen sehr schwammig. Also kurz dazu zwei Beispiele:

    Beispiel 1: GUI-Komponenten als Beans

    Wer schon einmal mit einem Gui Editor gearbeitet hat, wie zum Bsp dem NetBeans Gui Builder, gearbeitet hat, hat schon Beans verwendet ohne es vielleicht zu merken. Klickt man zum Beispiel im GUI Builder auf einen JLabel  kann man sich die Eigenschaften des Labels ansehen und diese dort auch gleich konfigurieren. SO kann man bequem und einfach die Hintergrundfarbe, Schriftart, den Text und diverse andere Eigenschaften sofort und bequem ändern, ohne dafür programmieren zu müssen oder erst extra die API zu bemühen um nachzusehen, mit welcher Methode man die vertikale Ausrichtung ändern kann.

    Da es natürlich etwas ineffizient wäre, für jede erdenkliche Komponente eine starre Konfig-Oberfläche zu bauen, ist es viel bequemer, per Introspection, die Komponente nach ihren Attributen zu fragen und die entsprechenden Elemente dynamisch erstellen zu lassen. Auf diese Art und weise kann man dann auch jede erdenkliche Bean konfigurieren – egal ob GUI Komponente von Sun oder selbst erstellt.

    Beispiel 2: Konfigurierbare Algorithmen als Beans

    ImageJ ist ein Java-Programm das einem per API sehr umfangreiche und vor allem schnelle Bildbearbeitung ermöglicht. Des weiteren lassen sich sehr leicht eigene PlugIns schreiben. Will man nun einen beliebigen Algorithmus schreiben, kann man diesen entweder parameterlos starten (z.B: “Bild horizontal spiegeln”) oder man benötigt noch eine Benutzereingabe (“Bild um X-Grad im Uhrzeigersinn drehen”). In ImageJ wurde dabei die Möglichkeit gewählt, einen generischen Dialog erzeugen und auslesen zu können. Alternativ hätte man auch hier JavaBeans einsetzen können um die Gui vollautomatisch erzeugen zu können, ohne dass sich der Programmierer darum kümmern muss.

    Eine einfache Beans GUI

    Ziel:

    • Eine einfache JavaBean mit einem Double und einem boolean-Wert und
    • ein einfacher Frame mit einem JTable, der aussieht wie die Komponente im NetBeans Gui Builder.

    Problem:

    • Wie verknüpft man die ganzen Klassen aus dem java.beans-Package?
    • Wie bringe ich der GUI bei, die Änderungen an die Bean zu propagieren?

    Lösung:

    Noch nicht ideal aber ausbaufähig, besteht mein Beispiel aus 5 Dateien:

    1. eine BeanModel Klasse die ein DefaultTableModel erweitert
    2. eine BeanTable klasse die einen JTable erweitert
    3. MyTestBean – die eigentliche JavaBean
    4. MyTestBeanBeanInfo – Beanbeschreibungsklasse
    5. TestFrame, der kleine Frame der das ganze visualisiert

    Das ganze gibt’s natürlich auch als ZIP zum Download / und als NetBeansProjekt.

    Unschön finde ich derzeit, dass ich sowohl das Modell ALS AUCH den JTable erweitern musste. Aber – ehrlich gesagt hatte ich gestern Nacht um halb 12 auch keinen Nerv mehr, das noch schöner zu machen.

    relevante Links:

  • System.gc() – gut gemeint, aber meist unnötig

    Vor ein paar Tagen durfte ich mal wieder einen Blick in Fremdcode werfen, um zu sehen, wie die entsprechende Implementierung realisiert wurde. Eine an sich recht übersichtliche Methode, endete dann mit einem System.gc();. Die Intention ist schon klar: “Gib bitte all den Speicher frei, der jetzt noch durch herrenlose Objekte belegt wird.” Das ist zwar gut gemeint, aber im Regelfall erstens unnötig und zweitens oft sogar kontraproduktiv.

    Zu den Fakten. Als erstes sollte an der Stelle ein Blick in die API von System.gc() folgen:

    Calling the gc method suggests that the Java Virtual Machine expend effort toward recycling unused objects in order to make the memory they currently occupy available for quick reuse. When control returns from the method call, the Java Virtual Machine has made a best effort to reclaim space from all discarded objects.

    Das heißt die API impliziert hier schon, dass man sich nicht darauf verlassen kann und soll, dass nach dem Aufruf überhaupt irgendetwas passiert ist. (Die nächst schlimmere Lösung, die ich auch ab und zu gesehen habe, ist dann eine Schleife, in der der GC X-mal aufgerufen wird.)

    Auf Stackoverflow findet sich eine interessante Diskussion, ob und warum der GC-Aufruf keine gute Idee ist – bzw WANN es eine gute Idee ist, den Aufruf wirklich zu machen. Ein kleines Fazit der ganzen Diskussion:

    • Es wird oft gesagt, dass es Bad-Practice ist, also lass es (naja okay, kein gutes Argument)
    • Die JVM kennt viele GCs, man weiß zur Ausführungszeit gar nicht, welcher GC aktiviert ist und wie er konfiguriert ist. Einfach mal auf der Java HotSpot VM Options nach “garbage collection” suchen.
    • Die sinnvollere Art den GC zu konfigurieren ist nicht ihn einfach aufzurufen sondern ihn zu konfigurieren.
    • Je nach Implementierung, kann ein Stop-The-World passieren. Also dass das gesamte Programm zur Garbage Collection steht.
    • Eventuell geschieht auch gar nichts: http://bugs.sun.com/view_bug.do?bug_id=6668279
    • Die Speicherverwaltung in der JVM ist nicht nur in Stack und Heap unterteilt. Der Heap ist unterteilt in Heap,Young,Tenured und Perm generation. Sun hat viel Zeit in die intelligente Garbage Collection gesteckt. Wenn man sich nicht mit Speicher Verwaltung und Garbage Collection beschäftigt, macht man es wahrscheinlich weniger intelligent als die Automatik.
    • Oracle/Sun schlägt im Tuning Guide “Tuning the Java Runtime System” explizit vor, den Aufruf auszuschalten.
    • .. und vermutlich noch einige weitere Argumente.

    Wann es dann wirkliche eine gute Idee ist, den garbage collect selbst aufzurufen, ist dort auch zu lesen. Unter anderem, ist ein manueller GC sinnvoll wenn:

    • Wenn man ein Speicherleck finden will, kann es sinnvoll sein, zu bestimmten Checkpunkten die Garbage Collection zu forcieren (oder es zu versuchen)
    • Wenn man den Speicherverbrauch von Klassen bestimmen will (siehe Posting).
    • Nach einer umfangreichen und langen Initialisierungsphase ist die Tenured-Generation vermutlich voll mit Objekten, die man nicht mehr brauchen wird und die man gleich aufzuräumen will/muss, um zu verhindern, dass der erste spätere GCs lange braucht, da dort enorm viele Objekte herumlungern die schon lange nicht mehr gebraucht werden.
    • Nach einer kurzen Initialisierungsphase sind eventuell viele – später nicht mehr benötigte – Objekte im Speicher, die gar nicht erst in die Tenured Generation wandern sollen.

    Interessante Links zum Thema:

    Tuning the Java Runtime System

  • Speicherverbrauch in Java oder “Size does matter!”

    Eines der Vorurteile gegenüber Java ist ja der (angeblich) enorme Speicherverbrauch. Frage ich dann, ob denn die entsprechende Applikation schon mal auf Speicherverbrauch geprofiled wurde und welcher Profiler verwendet wurde, gibt es große Augen und Gestammel über HeapSize, OutOfMemoryExceptions und dass in C ja eh alles besser sei. Na, da weiß man doch gleich dass nicht nur Java schuld sein muss. – Hat man mal mit ImageJ gearbeitet, ist man ab und an schon äußerst verwundert, wie schnell Java sein kann – und fühlt sich auch angespornt seine eigenen Kenntnisse  zu erweitern.

    Generell gibt es zur Speicherdiskussion (mindestens) zwei Szenarien.

    1. Die Diskussion, wieviel Speicher eine Datenstruktur verbraucht und ob nicht eine andere Speicherstruktur besser ist.
    2. Wir haben eine OOME und müssen sie beseitigen.

    Wieviel Speicher verbraucht meine Datenstruktur?

    DAS ist jetzt mal wirklich ein Nachteil von Java wie er im Buche steht, denn es gibt per se keine wirklich einfache Möglichkeit, den Speicherverbrauch einer Struktur oder eines Objektes zu ermitteln. Der Artikel From Java code to Java heap ist hier definitiv anzuraten. Hier wird detailierter über den Speicherverbrauch von Klassen eingegangen.

    Im Java Specialists Newsletter von 2001(!!) gibt es einen einen Workaround und ein paar weitere Erklärungen – es folgt eine teils Übersetzung aus dem Newsletter:

    1. Jede Klasse belegt mindestens 8 Bytes auf dem Heap (also auch ein new Object()).
    2. Jeder Datentyp belegt 4 Bytes, außer long und double, die 8 Bytes belegen. Achtung, das heißt, auch ein Datentyp byte benötigt dann 4 Bytes. Außerdem wird der Speicherverbrauch nur in 8 Byte Schritten erhöht. D.h eine Klasse mit einem byte Datentyp belegt 8 Byte für die Klasse + 8 Byte für die Daten = 16 Byte.
    3. Arrays sind speicherschonender  – der geneigte Leser darf das gerne selbst nachlesen.
    4. String#intern() kann ordentlich Speicher sparen.
    5. Boolean.TRUE und Boolean.FALSE benötigen weniger als new Boolean(true).

    Okay, alles schön und gut. Aber eine komplexere Struktur benötigt dann wieviel genau? Im Java Specialists Newsletter ist dazu eine kleine aber feine Klasse, die hier weiterhilft:

    public class MemoryTestBench {
    
        public long calculateMemoryUsage(ObjectFactory factory) {
            Object handle = factory.makeObject();
            long mem0 = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
            long mem1 = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
            handle = null;
            System.gc();System.gc();System.gc();
            System.gc();System.gc();System.gc();
            System.gc();System.gc();System.gc();
            System.gc();System.gc();System.gc();
            mem0 = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
            handle = factory.makeObject();
            System.gc();System.gc();System.gc();
            System.gc();System.gc();System.gc();
            System.gc();System.gc();System.gc();
            System.gc();System.gc();System.gc();
            mem1 = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
            return mem1 - mem0;
        }
    
        public void showMemoryUsage(ObjectFactory factory) {
            long mem = calculateMemoryUsage(factory);
            System.out.println(factory.getClass().getName() + " produced " + factory.makeObject().getClass().getName() + " which took " + mem + " bytes");
        }
    }
    

    Die ObjectFactory sieht so aus:

    public interface ObjectFactory { public Object makeObject(); }

    Und am Beispiel einer ByteFactory sieht das wiederum so aus:

    public class ByteFactory implements ObjectFactory { 
       public Object makeObject() { return new Byte((byte)33); } 
    }
    

    Jup, etwas aufwändig. Aber immerhin ein Ausweg aus dem Dilemma um hypothetische Diskussionen was wohl besser sein könnte. Und ja, DAS ist in C wirklich einfacher – und trotzdem will ich weiter Java verwenden :-D

    OMG, OOME – was tun?!

    Regel 1: NICHT blindwütig irgendwo irgendwas irgendwie anders machen.
    Regel 2: Auch nicht nachdenken und glauben zu wissen wo es weh tut.

    Sondern? Messen!
    Zum Beispiel mit der JVisualVM, die bei neueren SUN/Oracle JDKs (nicht JRE) bereits im bin-Verzeichnis der JVM mitgeliefert wird. Ist man eh mit NetBeans unterwegs, kann man das Programm auch nochmal von dort direkt profilen. Ich persönlich setze den erlaubten Speicher (also -Xmx) dann gleich kleiner an, damit die OOME schneller eintritt und weniger Daten betrachtet werden müssen.

    Mit etwas Glück sieht man dann recht schnell, welche Datenstrukturen (zu) oft im Speicher sind und kann dann gezielter nach den Referenzen suchen, die es eigentlich gar nicht geben sollte.