PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Java - Speicherverwaltung


ooAlbert
2009-03-25, 20:43:25
Hi,

ich hab mal eine Frage zum Speichermanagment in Java. Für gewöhnlich hat man ja nichts damit zu tun und Java macht das ganz alleine. Ich hab jetzt mal meine Anwendung mit "JConsole" betrachtet und den Speicher protokolliert. Mir ist zwar nicht ganz klar was die ganzen Unterteilungen genau bedeuten aber ich denke wichtig ist vor allem die "Heap" anzeige. Da kann ich unter anderem sehen wieviel Speicher überhaupt angefordert wurde vom System. Wenn das nicht reicht wird mehr angefordert, soweit klar aber verringert das System die angeforderte Menge auch wieder selbstständig und kann man sagen unter welchen Umständen das passiert? Der GC läuft ja munter vor sich hin und räumt den Heap auch immer wieder leer.

Denn in diesem Speicherdiagramm kann ich sehen, das der Heap bis zur ersten angeforderten Menge vollgeschrieben wird dann wird er schlagartig geleert und es beginnt von vorn. Das wäre jetzt kein Problem, wenn nach solch einer Bereinigung die angeforderte Heap-Menge nicht erhöht wäre. Irgendwann ist ja ein theoretisches Maximum erreicht.

mfg

Gast
2009-03-25, 23:14:52
Hi,

ich hab mal eine Frage zum Speichermanagment in Java. Für gewöhnlich hat man ja nichts damit zu tun und Java macht das ganz alleine. Ich hab jetzt mal meine Anwendung mit "JConsole" betrachtet und den Speicher protokolliert. Mir ist zwar nicht ganz klar was die ganzen Unterteilungen genau bedeuten aber ich denke wichtig ist vor allem die "Heap" anzeige. Da kann ich unter anderem sehen wieviel Speicher überhaupt angefordert wurde vom System. Wenn das nicht reicht wird mehr angefordert, soweit klar aber verringert das System die angeforderte Menge auch wieder selbstständig und kann man sagen unter welchen Umständen das passiert? Der GC läuft ja munter vor sich hin und räumt den Heap auch immer wieder leer.

Denn in diesem Speicherdiagramm kann ich sehen, das der Heap bis zur ersten angeforderten Menge vollgeschrieben wird dann wird er schlagartig geleert und es beginnt von vorn. Das wäre jetzt kein Problem, wenn nach solch einer Bereinigung die angeforderte Heap-Menge nicht erhöht wäre. Irgendwann ist ja ein theoretisches Maximum erreicht.

mfg


mal wieder ein fall fuer gefaehrliches halbwissen in diesem forum. ich geh auf deine behauptungen bezueglich des heaps nicht ein und sage dir nur, dass sie falsch sind. schau bei wikipedia nach, wofuer der heap verwendet wird... kleiner tipp, gerade NICHT vom system... das naechste ist, dass es immer eine fragmentierung der speicherbereiche gibt, das ist unvermeidlich. ansonsten einen kleinen tipp, anstatt hier drauflos zu posten kauf dir doch ein paar gute buecher zum thema, ein guter einstieg in die informatik ist z.b. 'struktur und interpretation von computerprogrammen'. da lernst du dann auch wirklich was.

Trap
2009-03-25, 23:43:38
Wenn man eine Empfehlung zu SICP anbringen will, sollte man sich vorher die Mühe geben den Text zu lesen auf den man antwortet.

ooAlbert möchte Details zur Funktion des GC der JVM, die stehen in SICP sicher nicht. Einiges findet man in http://java.sun.com/docs/hotspot/gc5.0/gc_tuning_5.html (die breite GC Auswahl gibt nur in der EnterpriseEdition von Java) aber ob der GC irgendwann mal Speicher zum Betriebssystem zurückgibt weiß ich auch nicht.
Etwas allgemeiner ist http://java.sun.com/j2se/reference/whitepapers/memorymanagement_whitepaper.pdf , da steht es aber auch nicht explizit drin.

Ganon
2009-03-25, 23:52:49
Afaik ist das direkte Verhalten der GCs gar nicht direkt definiert, nur dessen Arbeitsweisen...

Man kann ja auch zwischen haufenweisen GCs wählen und bei diesen dann auch noch spezielle Unterarten. Es gibt unter Java ja nicht "den GC"...

Monger
2009-03-26, 00:27:13
Wenn das nicht reicht wird mehr angefordert, soweit klar aber verringert das System die angeforderte Menge auch wieder selbstständig und kann man sagen unter welchen Umständen das passiert?


Kurz: Nein!

Wie der GC genau arbeitet, ist ein Implementierungsdetail, und wird in aller Regel nicht offengelegt. Es gibt unter Java sogar nichtmal eine Pflicht dass der GC überhaupt jemals aufräumt. Vorallem bei Handhelds und Handys tut er das sogar tatsächlich nicht solange der Prozess läuft, weil es da Probleme mit der Speicherallokiierung gibt.

Die Implementierung des GC kann sich also von Version zu Version, von Plattform zu Plattform unterscheiden. Das ist nichts worauf man sich verlassen könnte.

ooAlbert
2009-03-26, 01:36:00
das würde also bedeuten, wenn ich pech habe läuft wir der Speicher irgendwann voll, weil der GC den schweizer Käse nicht mehr zusammen bekommt oder zu langsam ist? Ich bezog mich übrigens auch die ganz normale IRE-6 von Sun.

Coda
2009-03-26, 02:47:58
Wenn der Speicher vollläuft bei einer normalen VM wird natürlich der Garbage-Collector erstmal bemüht bevor man eine Exception schmeißt.

Monger
2009-03-26, 09:41:42
Zumindest im Mobile Bereich ist das ein ernsthaftes Problem. Da neigt man dazu, möglichst viele Objekte nur einmalig zu instanziieren und dann wiederzuverwenden, weil eben der GC aufgrund mangelnden Speichermanagements da nicht so komfortabel arbeiten kann.

Auf dem PC brauchst du dir aber über sowas keine Sorgen machen. Bevor du da den Speicher zumüllst, wirst du höchstwahrscheinlich über ganz andere Probleme stoßen.

Gast
2009-03-26, 11:23:55
Wenn man eine Empfehlung zu SICP anbringen will, sollte man sich vorher die Mühe geben den Text zu lesen auf den man antwortet.

ooAlbert möchte Details zur Funktion des GC der JVM, die stehen in SICP sicher nicht. Einiges findet man in http://java.sun.com/docs/hotspot/gc5.0/gc_tuning_5.html (die breite GC Auswahl gibt nur in der EnterpriseEdition von Java) aber ob der GC irgendwann mal Speicher zum Betriebssystem zurückgibt weiß ich auch nicht.
Etwas allgemeiner ist http://java.sun.com/j2se/reference/whitepapers/memorymanagement_whitepaper.pdf , da steht es aber auch nicht explizit drin.

meine empfehlung bezog sich auch nicht direkt auf die von ihm gestellte frage, sondern das nicht vorhandene fachwissen.

ooAlbert
2009-03-26, 12:36:27
also ich hab jetzt den Jconsole Monitor 24h laufen lassen und die Anwendung auch, achso das ist ein autonomer Dienst also produziert der selbst Daten. wie erfreulich steigt die speicherauslastung zwar an aber sobald die angeforderte Grenze erreicht wurde scheint der GC richtig aufzuräumen und das halt dann periodisch. Der Angeforderte Speicher hatte sich auch nur einmal erhöht auch wenn später immer mal über das Limit gegangen wurde.

zumindest ist das beruhigend zu wissen :) Aber um ganz sicher zu sein werd ich an geeigneter Stelle im Programm den GC aufrufen, bzw. den Hinweis zum Aufräumen absetzen :)

Trap
2009-03-26, 12:42:27
zumindest ist das beruhigend zu wissen :) Aber um ganz sicher zu sein werd ich an geeigneter Stelle im Programm den GC aufrufen, bzw. den Hinweis zum Aufräumen absetzen :)
Hast du irgendwo gelesen, dass das sinnvoll ist?

ooAlbert
2009-03-26, 15:01:41
Ich hab in anderen Beiträgen schon lesen können das es durchaus etwas bringt, zumal es ja nur ein Hinweis ist und kein wirklicher Aufruf. Außerdem verspreche ich mir davon, das ein autonomes Programm so einen konstanteren Speicherverbrauch hat. Immerhin war ja zu lesen, das der GC nicht zwangsweise alles schafft was wegzuräumen wäre.

Monger
2009-03-26, 15:29:34
zumindest ist das beruhigend zu wissen :) Aber um ganz sicher zu sein werd ich an geeigneter Stelle im Programm den GC aufrufen, bzw. den Hinweis zum Aufräumen absetzen :)
Das ist kontraproduktiv. Den GC explizit zu callen, verschlechtert meistens eher die Performance. Es ist auch keine Garantie dafür, dass der GC sofort aufräumt. Man kann das eher als dringliche Bitte verstehen, aber nicht als Befehl.

ooAlbert
2009-04-04, 21:53:49
ich nochmal :) ich hab jetzt die Anwendung die Zeit über laufen lassen mit der Überwachung durch Jconsole.

Mein Problem ist jetzt, wie ich genau die einzelnen Speicheraufteilungen auswerten soll.

Heap: "Eden Space", "Survivor Space", "Tenured Gen"
Non-Heap: "Perm Gen [shared-ro]", "Code Cache", "Perm Gen [shared-rw]", "Perm Gen"

Kann mir das wer erklären, was das überhaupt darstellt, bzw. was da drin liegt und was man daraus erkennen kann?

Bei mir steigt beispielsweise der Code-Cache an und Perm-Gen an in Non-Heap. Im Heap steigt wiederum Turned-Gen an.

Ich hab jetzt bedenken das ich doch irgendwie einen Speicherfresser gebastelt habe nur das es eben sehr langsam passiert :/

mfg

Achill
2009-04-07, 21:58:48
Hier werden die GCs recht gut Beschrieben: http://java.sun.com/javase/technologies/hotspot/gc/gc_tuning_6.html

ooAlbert
2009-04-07, 22:14:39
Ich hab hier noch sowas gefunden:
http://java.sun.com/j2se/1.5.0/docs/guide/management/jconsole.html#memory

Aber so richtig schlau werd ich aus dem Zeug nicht.

Wie hab ich dann zu bewerten, das der "Code-Cache" ansteigt? Da steht der enthält "Native Code". Ist das was das ich verursacht habe oder fällt das irgendwann man von selbst ab? Das selbe gilt für "Perm Gen".

Tenured-Gen soll die Objekte beinhalten, welche aus dem Survivor-Gen übrig sind, wenn ich das recht verstehe. Und im Survivor-Gen sind die Objekte, welche den GC überlebt haben.
Heißt das jetzt, der GC hats nicht geschafft oder die Objekte lassen sich nicht entfernen? Das wäre ja dann ein Anzeichen für ein Speicherlag oder eher nicht, das ich irgendwelche Objekte nicht freigebe oä.?

Köppchen
2009-04-16, 22:25:20
Hallo Albert,
ich kenne mich mit der Sun VM nicht sonderlich gut aus denn ich schlage mich üblicherweise mit Websphere rum. Aber das der Code Cache wächst ist normal, schließlich legt der JIT Compiler den Code dort ab. Entfernt wird der vermutlich nicht mehr (Ausser zum Programmende).
Beim generational GC sind im Tenured Heap solche Objekte die einige "kostengünstige" GC's überlebt haben. Diese Objekte können aber trotzdem nach einem Full GC wieder aus dem Speicher verschwinden. Objekte aus einem Speicherleck landen typischerweise in diesem Bereich.

PH4Real
2009-04-19, 16:57:28
zumindest ist das beruhigend zu wissen :) Aber um ganz sicher zu sein werd ich an geeigneter Stelle im Programm den GC aufrufen, bzw. den Hinweis zum Aufräumen absetzen :)

Kurz nochmal dazu:
Wie schon gesagt, es ist nicht sinnvoll.

Wenn, dann bringen Dir (zumindest für die SunVM) die ganzen -Xflags was, womit Du genauer einstellen kannst, wie sich der GC verhalten soll (wurde glaube ich schon verlinkt).

Falls Du jedoch auf OutOfMemoryExceptions läufst trotz z.b. AggressiveHeap Optionen (Achtung: das kann massiv die Performance beeinflussen) oder so, hast Du Dir höchstwahrscheinlich Speicherlöcher gebaut.

Singleton Patterns eignen sich hervoragend dazu solche zu produzieren ;)... aber das ist nicht der einzige Grund warum man versuche sollte diese zu meiden.