-
Hi Leute,
eigentlich sollte es dieses Thema in Java wegen GC nicht geben. Trotzdem hab ich in meinem Programm doch argen Ressourcenverbrauch, welcher auch nicht wieder durch den GC freigegeben wird. Es ist so, ich lade Unterprogramme(JPanel) in ein JTabbedpane. Über einen integrierten Schließbutton wie Firefox/IE kann man den Tab wieder schließen. Die Panels hängen auch einzig allein in dem Tab und werden nirgendswo sonst referenziert.
Problem ist nun dass man nach zirka 30 verschiedenen Tabs ungefär 200 MB Arbeitsspeicher besetzt. Schließe ich nun die Tabs bleibt trotzdem 200 MB besetzt, dieses Spielchen zieht sich bis zirka 310 MB fort. Ab da an reagiert der GC, das Programm ist dann aber sehr träge. Gibt es ne möglichkeit den Speicher schon vorher wieder frei zu bekommen bzw. kennt ihr vlt. ein Plugin zur Analyse für Eclipse.
Gruß Jan
-
24.09.10 11:03 #2Elmu Tutorials.de Gastzugang
-
27.09.10 20:41 #3
- Registriert seit
- Apr 2007
- Beiträge
- 153
Hallo,
du könntest vielleicht mal folgendes versuchen.
Anstatt dass du immer mit new einen neuen JPanel erstellst (kurzlebiges Object) der nach der Verwendung von JPanel wieder durch den GC freigegeben werden müsste, könntest du ja auch von Beginn an mehre JPanels in den Speicherladen und immer einen freien bei bedarf anzeigen (ggfs. neu initialisieren bzw. reseten.
Du würdest sozusagen deine JPanels recyclen.
Du kannst ja zu beginn soviele JPanels erstellen, wie du den maximal Wert erwartest z. B. 8 oder 16. Im Schlimmsten Fall musst du dir bei Bedarf neuen Speicher beschaffen. Du könntest die JPanels ja in einer möglichst statischen (also lieber Array List anstelle von Linked List) Collection speichern.
Selbst wenn du jetzt im modernen JAVA programmierst, kannst du ja trotzdem das ältere Prinzip aus den C-Zeiten verwenden, in der man den Speicher immer möglichst statisch reserviert hat und dieses dynamische gedöns mit malloc vermieden hat. Das ist nämlich von Grund auf Böse
Geändert von Tikonteroga (27.09.10 um 20:46 Uhr)
-
29.09.10 07:51 #4
- Registriert seit
- Aug 2005
- Ort
- Karlsruhe (Baden-Württemberg)
- Beiträge
- 905
Hast du dein Programm mal mit der JConsole analysiert (oder anderen Speicheranalyse-Tools)?
Oder hast du deinem Programm zu viel Speicher gegeben und der GC muss dann viel aufräumen? (vlt ein Stop the world GC sogar?)Wäre super wenn ihr euren Code in dieser Form einfügt:
[java]System.out.println("Hello World");[/java]Code java:1
System.out.println("Hello World");
Für erledigte Threads dürft ihr den "erledigt"-Button anklicken!
Über Dank freut sich jeder, der euch geholfen hat - ein Klick auf "Danke" kostet ja nicht mal was
Blog: http://javaeffective.wordpress.com/
-
-
29.09.10 09:06 #6
- Registriert seit
- Aug 2005
- Ort
- Karlsruhe (Baden-Württemberg)
- Beiträge
- 905
Wenn du deinem Java-Programm nichts angibst werden die Standard-Einstellungen zum Speicher der VM verwendet.
Der Standard-Heap-Size ist bei einer Sun(Oracle) VM 64MB (32bit) oder 30% mehr bei 64bit.
Bei eclipse ist der Standard-Speicher bereits erhöht worden. (eclipse.ini)
JConsole ist ein Standard-Programm, welches in der Sun-JDK enthalten ist. JVisualVM ist auch nicht zu verachten
Wäre super wenn ihr euren Code in dieser Form einfügt:
[java]System.out.println("Hello World");[/java]Code java:1
System.out.println("Hello World");
Für erledigte Threads dürft ihr den "erledigt"-Button anklicken!
Über Dank freut sich jeder, der euch geholfen hat - ein Klick auf "Danke" kostet ja nicht mal was
Blog: http://javaeffective.wordpress.com/
-
Jut soweit, alles kla. Nun ja aber im Prinzip handelt es sich um ein noch recht Simples Programm und jetzt schon an der Heap Size rumzubastelt halte ich für zu früh, deswegen wollte ich erst mal gucken ob ich das Problem nicht so in Griff bekomme. Vor allendingen wenn die Heap-Size auf 64 MB beschränkt ist, wieso klettert dieser bis auf zirka 320 MB und wieso springt erst dann der GC richtig ein?
-
29.09.10 10:38 #8
- Registriert seit
- Aug 2005
- Ort
- Karlsruhe (Baden-Württemberg)
- Beiträge
- 905
Ganz einfach, weil die JVM auch einen großen Speicher-Overhead mitbringt.
Eine andere Frage, benutzt du ein JRE oder ein JDK? Hast du ein 64bit OS oder Linux?
Der Hintegrund der Frage ist, dass es 2 verschiedene Modis der VM gibt. Nämlich client und server. Und je nach Architektur und OS wird eins Standardmässig gewählt.
Vielleicht hilft dir ein -client als VM-Argument.Wäre super wenn ihr euren Code in dieser Form einfügt:
[java]System.out.println("Hello World");[/java]Code java:1
System.out.println("Hello World");
Für erledigte Threads dürft ihr den "erledigt"-Button anklicken!
Über Dank freut sich jeder, der euch geholfen hat - ein Klick auf "Danke" kostet ja nicht mal was
Blog: http://javaeffective.wordpress.com/
-
Also System ist XP 32 Bit ein JDK glaub ich zu benutzen, wie sollte ich sonst Entwickeln können oder kann man auch irgendwo das JRE als VM starter einstellen?
-
29.09.10 18:37 #10
- Registriert seit
- Apr 2007
- Beiträge
- 153
Hallo,
ich glaube euer Lösungsansatz ist falsch. Die Einstellungen der JVM sind nicht das Problem. Ist wohl auch egal welches OS installiert ist.
Das Problem ist ja dass zur Laufzeit der Anwendung zu oft Speicher angefordert wird, der aber nur kurz gebraucht wird (kurzlebiges Objekt). Man sollte eher versuchen den angeforderten Speicher wiederzuverwenden, damit man über die Laufzeit weniger Speicher mit 'new' anfordern muss. Denn das freigeben von Speicher durch den GC kostet Performance ...
Vielleicht könntest du ja mal beschreiben, was das für Unterprogramme sind, die du verwendest.
Gruß
Tikonteroga
-
Ja dies hattest du ja auch schon oben beschrieben ich werde diesen Ansatz in so weit es möglich ist umzusetzen. Es ist halt nur insofern Problematisch, dass es inzwischen 20 verschieden Panels sind die ich mir dynamisch in die JTabbedPane lade. Demnach müsste ich ja die Referenzen in einem Array zwischen lagerne und dann bei einem Aufruf über diese Irretieren um zu schauen ob ein passendes dabei ist. Meinst du nicht dass unter Umständen dieses Array und damit dass massive Vorhalten der Objekte Ressourcenzehrender wär?
Gruß Jan
-
30.09.10 08:02 #12
- Registriert seit
- Aug 2005
- Ort
- Karlsruhe (Baden-Württemberg)
- Beiträge
- 905
Wieso durch iterieren?
Dafür gibt es Maps/Sets, wo du nur noch nach einem passenden Schlüssel/Inhalt suchen musst.
Z.B. HashMapWäre super wenn ihr euren Code in dieser Form einfügt:
[java]System.out.println("Hello World");[/java]Code java:1
System.out.println("Hello World");
Für erledigte Threads dürft ihr den "erledigt"-Button anklicken!
Über Dank freut sich jeder, der euch geholfen hat - ein Klick auf "Danke" kostet ja nicht mal was
Blog: http://javaeffective.wordpress.com/
-
30.09.10 09:42 #13
- Registriert seit
- Apr 2007
- Beiträge
- 153
Hallo,
also das Iterieren über ein Array mit 20 Elementen und 1-2 Vergleiche ist glaube ich vernachlässigbar oder zumindest das kleinere Übel gegenüber dem freischaufeln von über 100 MB durch den Garbage Collector.
Bei HashMaps solltest du auch möglichst aufpassen, dass du nicht gerade einen String als Key verwendest. Falls du jedes der Panel als eigene Klasse erstellt hast, die von JPanel ableitet, könntest du vielleicht Class<?> als Key verwenden. Ich hab da auch schon eine Collection gesehen, die den Typ überprüft. Ich weiss aber nicht mehr, ob das JAVA war. Ich glaube eher das es .NET war.
Du könntest deinen Code ja auch mal allgemein durchsuchen und schauen ob du z. B. in Schleifen kurzlebige Objekte mit 'new' erzeugst, String Objekte mit dem '+' Operator aneinanderhängst. Es ist auch immer sehr förderlich, wenn du Arrays und Collections sowie StringBuilder immer mit einer Capacity initialisierst (Worst Case), die sich zur Laufzeit nicht mehr verändern muss.
Zur Erklärung: Wenn eine ArrayList oder ein StringBuilder eine bestimmte Capacity erreicht hat (z. B. 75 %), dann wird ein neuer und größerer Speicher angefordert und der Inhalt aus dem alten Speicherbereich in den neuen kopiert. Der alte Speicherbereich ist aber erst freigegeben, wenn ihn der GC freigibt. Und du hast ja gesehen, dass der GC das nicht ideal macht bzw. machen kann ...
Zudem solltest du diese Klassen nicht immer wieder neu erstellen, sondern sie wiederverwenden indem du sie entleerst (StringBuilder.setLength(0) und Collection.clear()). Du musst dann halt aufpassen, dass du den reset nicht vergisst ...
Gruß
TikonterogaGeändert von Tikonteroga (30.09.10 um 09:46 Uhr)
-
Ja natürlich, nicht dran gedacht.
Dies ist so, aber jetzt alle möglichen Objekte in Schleifen wieder verwenden wird das eine heiden arbeit sein. Eigentlich leben doch Schlaufen genau davon, dass man halt sich kurzlebiger Objekte Bedient um irgendwelche Daten aufzubauen.
Naja ich werd mal schauen ob das was bringt.
Danke trotzdem auch an die Anderen für die Tips
Geändert von ElJarno (30.09.10 um 10:17 Uhr)
-
30.09.10 12:31 #15
- Registriert seit
- Aug 2005
- Ort
- Karlsruhe (Baden-Württemberg)
- Beiträge
- 905
Ja, aber Strings in Schleifen mit + zusammen zu bauen ist tödlich. Da jedes mal ein neuer Ergebnis-String und ein StringBuilder erstellt wird.
Daher soll man da manuell einen StringBuilder verwenden.Geändert von Anime-Otaku (30.09.10 um 12:55 Uhr)
Wäre super wenn ihr euren Code in dieser Form einfügt:
[java]System.out.println("Hello World");[/java]Code java:1
System.out.println("Hello World");
Für erledigte Threads dürft ihr den "erledigt"-Button anklicken!
Über Dank freut sich jeder, der euch geholfen hat - ein Klick auf "Danke" kostet ja nicht mal was
Blog: http://javaeffective.wordpress.com/
Ähnliche Themen
-
Url Zerlegen und ein wert wieder geben!?
Von harderph im Forum PHPAntworten: 6Letzter Beitrag: 26.03.08, 12:43 -
2 Abfragen aus 2 tabellen und dann in einer wieder geben?
Von harderph im Forum Relationale DatenbanksystemeAntworten: 1Letzter Beitrag: 28.01.08, 22:04 -
Speicher lässt sich nicht wieder frei machen
Von Ivan der Schrecken im Forum VisualStudio & MFCAntworten: 0Letzter Beitrag: 17.10.04, 19:57 -
Bilder wieder geben
Von Arbeiter im Forum PHPAntworten: 6Letzter Beitrag: 06.08.04, 08:46 -
Programm zum Speicher frei machen...
Von mirscho im Forum Microsoft WindowsAntworten: 7Letzter Beitrag: 05.11.02, 14:03



3Danke

Zitieren
Login





