Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

1

11.02.2013, 19:45

Memory Leak Java RCP SWT JFace

Hallo,

ich habe anscheinend einen recht großen Memory Leak in meiner Anwendung und verstehe nicht ganz warum bzw. ich finde ihn auch nicht.
Es handelt sich um eine RCP Anwendung, mit der ich übungshalber einen Towerdefense Editor erstelle um mich ein wenig in das Ganze einzuarbeiten. Momentan erstellt es eine Karte mit einem Hintergrundbild und ansonsten eigentlich nicht viel mehr.

Wenn ich nun Karten lade, scheint der Speicherplatz der alten Karte nicht freigegeben zu werden, wenn ich mich mit JConsole verbinde und im Memory TAB nachschaue. Kann mir vielleicht jemand sagen, woran das liegt?

hier die Methode, die bei load aufgerufen wird

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public void load(String mapFilePath)
    {
        try
        {
            FileInputStream fin = new FileInputStream(mapFilePath);
            ObjectInputStream ois = new ObjectInputStream(fin);
            setMap((TDMap) ois.readObject());
            ois.close();
            fin.close();
        }
        catch (FileNotFoundException e)
        {
            e.printStackTrace();
        }
        catch (ClassNotFoundException e)
        {
            e.printStackTrace();
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
    }


setMap

C-/C++-Quelltext

1
2
3
4
5
6
7
8
public void setMap(TDMap map)
    {
        if (this.map != null)
            this.dispose();

        changeSupport.firePropertyChange("Map", this.map, this.map = map);
        initMapCanvas();
    }


dispose

C-/C++-Quelltext

1
2
3
4
5
6
7
8
public void dispose()
    {
        if (imgBackground != null)
            imgBackground.dispose();

        if (batchImage != null)
            batchImage.dispose();
    }


und initMapCanvas

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
private void initMapCanvas()
    {
        Bundle bundle = FrameworkUtil.getBundle(this.getClass());
        URL url = FileLocator.find(bundle, new Path("icons/" + map.getBackground()), null);
        imgBackground = ImageDescriptor.createFromURL(url).createImage();

        mapCanvas.getParent().setBounds(0, 0, map.getWidth(), map.getHeight());
        mapCanvas.getParent().setBackgroundMode(SWT.INHERIT_DEFAULT);
        mapCanvas.setBounds(0, 0, map.getWidth(), map.getHeight());
        batchImage = new Image(mapCanvas.getDisplay(), map.getWidth(), map.getHeight());

        mapCanvas.redraw();
    }





Eigentlich sollten die Bilder ja immer disposed werden, bevor eine neue Karte geladen wird, aber laut Memoryübersicht ist dem nicht so. In TDMap ist nichts besonderes drin, außer int/String Werte. Hier noch der restliche Quellcode, falls ihn jemand benötigt.

https://dl.dropbox.com/u/6414966/src.zip

Ich entwickle in Eclipse HELIOS Service Release 2 und dem JDK 1.7.0_05.
Es scheint auch so, als würde der HEAP-Speicher kontinuierlich wachsen, was mich auch etwas wundert. Vielleicht ist das auch alles normal, aber falls sich hier jemand besser damit auskennt, dann möge er mich bitte erleuchten^^

Vielen Dank

2

11.02.2013, 20:57

Also ich merke null Probleme mit der Performance, wobei ich wohl etwas sehr überdimensioniert bin für dieses Miniprogramm mit meinen 12GB RAM. Vielleicht ist das Verhalten ja auch ganz normal, ich hätte nur gerne Gewissheit.

Das mit dem disposen wusste ich bereits und ich überschreibe dispose eigentlich nirgends, außer halt in Bereichen, wo z.b. Images/Fonts/Colors mit new erzeugt werden, da diese im dispose extra freigegeben werden müssen.
Danke trotzdem :)

3

11.02.2013, 22:45

Probier mal die maximale Heap Größe zu verringern z.B. -Xmx64m als Startparameter der VM mit geben, dann solltest Du das dispose-Verhalten überprüfen können. Um sicherzustellen, dass entsprechend oft dispose aufgerufen wird, kannst Du sonst einfach mal das ganze in die Log-Ausgabe schreiben oder mitzählen usw.

Wenn Du Java 7 nutzt kannst Du außerdem mal try with resources und multi catch benutzen.

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

4

12.02.2013, 06:59

Wobei ich das gecatche da sehr fragwürdig finde. Speziell wohl die ClassNotFoundException.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

Werbeanzeige