Memory Management in Java

NetzUnity und Informatik-forum wurden zusammengelegt. Eine entsprechende Ankündigung wird demnächst noch folgen. Für 2025 ist hier einiges geplant! Bei Fragen bitte per DM an Maximilian Rupp wenden.
  • Nehmen wir den Fall, ich habe eine Java Servlet Application, welche zu 100% Memory Leaks hat, die ich entfernen möchte, wobei eigentlich möchte ich die Application nur performanter machen.
    Es gibt folgende Möglichkeiten die Performance zu optimieren:
    A) Memory Leaks entfernen
    B) optimales Feintuning der VM + Garbage Collector

    ad A) Hat jemand schon mal eine der folgenden SoftwareLösungen getestet und kann mir eine empfehlen?

    ad B) Welche Möglichkeiten habe ich um an der VM herumzuschrauben?
    (Dass ich meinen Tomcat Server in der catalina.bat spezielle Einstellungen bezüglich des erlaubten Speicherverbrauchs für die VM mitgeben kann, weiß ich)
    Wie kriege ein feintuning für den GC hin?
    (So dass er aber auch noch kostengünstig auf einem Host/Großrechner läuft)
    Stimmt es, dass die VM folgendermassen arbeitet:
    Memory wird voll -> Gegenmassnahme: Mehr Speicher anfordern
    Memory wird wieder voll und kein weiterer Speicher laut den VM Settings zulässig -> Gegenmassnahme: GC wird aktiviert (ja, erst jetzt wird er aktiviert)
    Memory wird abermals voll -> Gegenmassnahme: Mehr Speicher vom System anfordern
    Memory wird abermals voll -> Gegenmassnahme: "Absturz" mit der Fehlermeldung "bla bla bla, Java hat nicht genug Arbeitsspeicher zur Verfügung (oder so ähnlich)"

    ---
    There are only 10 types of people in the world: those who understand binary and those who dont

    Wo war noch mal die Äniki-Taste ????

  • also um in einem java-programm memory leaks zu produzieren musst du aber schon wilde scheisse programmen (;) sorry nicht persönlich nehmen)

    aber mal ernst: wenn du eine referenz nicht überschreibst erkennt der garbage collektor automatisch ob ein objekt noch benötigt wird!!!

    und es gibt auch eine methode um die priorität des GC's "hochzuschrauben" um ihn zu veranlassen den speicher zu defragmentieren... (weiß aber leider nicht mehr wie die heißt -> help nachsehn!)

    mfg marX

  • also die wilde scheiße will ich mal überhört haben ;)
    das proggi is schon etwas groß und soll mal wenns fertig is ca. 1,5 - 2 mio zeilen c++ code nachbilden
    ich würd mal sagen da sind memory leaks schon vorprogrammiert, vor allem wenn die datenbank dahinter mit unheimlich großen datenmengen daherkommt

    but however, soweit ich weiß arbeitet der gc nicht perfekt und "übersieht" die eine oder andere referenz
    und wenn du jetzt auf unsere application 100-500 user gleichzeitig los lässt macht sich auch der kleinste programmier-fehler bemerkbar (ist schliesslich eine webapplication - servlet)

    bez. priorität hochschrauben, wenn du da eine ressource zum nachlesen kennst bitte mir mitteilen, denn auch dies ist nicht so einfach, wenn du das teil u.a. für den host mitentwickelst, denn da kostet jeder abgesetzte befehl geld, und wenn ich den gc per hand aufrufe hab ich vielleicht einen freien speicher aber der kunde geht ein weil es ihm sein letztes hemd kostet (siehe user anzahl)

    vermutlich habe ich das prob nicht gut genug beschrieben, hoffe dies hilft den umfang besser einzuschätzen

    ---
    There are only 10 types of people in the world: those who understand binary and those who dont

    Wo war noch mal die Äniki-Taste ????

  • vielleicht bin ich jetzt auf dem holzweg, aber ich glaube ihr habt euch misverstanden, weil ihr dem begriff 'memory leak' eine unterschiedliche bedeutung gebt:

    marX meint damit, das ein objekt im speicher verbleibt, ohne das eine referenz auf das objekt existiert (klassisches c++ problem, wenn man nicht gescheit aufräumt). Das Objekt bleibt dann bis zum Programmende im Speicher, es entsteht ein Leck => Memory Leak.

    In Java kann das aber nicht passieren, es sei denn durch einen riesen bug im gc.

    Mad_Max spricht glaub ich von Memory Leaks im Sinne von unnötig hohem Speicherverbrauch, der durch designfehler irgendwo im programmcode entstanden ist. Darum will er auch Infos zu den im originalposting erwähnten tools, um die betreffenden Stellen zu finden und den code zu optimieren.

    habe ich damit recht oder hab _ich_ jetzt am ziel vorbeigeschossen? ;)

    die tools kenne ich übrigens alle nicht (JProbe vom Namen her), wenn du(Mad_Max) die noch testest wäre es nett, wenn die resultate posten könntest.


    PS: Ich versuche schon seit wochen, bei solchen postings nur noch in kleinbuchstaben zu schreiben, das ist viel schwerer als man glaubt :)

  • zunächst einmal, du hast recht und bist nicht aufm holzweg, aber soweit ich weiß arbeitet der gc auch nicht optimal, und es kann vorkommen, dass er denkt dass man noch irgendwann mal auf dieses objekt zugreifen kann (obwohl man nicht mehr kann) und die wandeln als zombies (siehe c++ unreferenzierte pointer) im speicher "herum" ;)
    irre ich mich da grad gewaltig?

    ich werde gerne die resultate posten, kann jedoch noch etwas dauern, weil wir im moment sowieso ein komplettes redesign vornehmen.

    how ever, 1. finde ich es nicht schwer nur "klein" zu posten, und 2. finde ich es eine frechheit dass du schon so viele posts hast ;)

    ---
    There are only 10 types of people in the world: those who understand binary and those who dont

    Wo war noch mal die Äniki-Taste ????

  • Zitat von Mad_Max

    zunächst einmal, du hast recht und bist nicht aufm holzweg, aber soweit ich weiß arbeitet der gc auch nicht optimal, und es kann vorkommen, dass er denkt dass man noch irgendwann mal auf dieses objekt zugreifen kann (obwohl man nicht mehr kann)

    wär mir neu, dass er sowas tut. eine schnelle google-recherche zeigt nur, dass es das problem der ungewollten referenz gibt (siehe zB hier), die aber technisch kein leak ist, sondern ein unfähiger programmierer ;).
    ansonsten sollte da nichts verloren gehen.

    Zitat

    finde ich es eine frechheit dass du schon so viele posts hast ;)

    *hust*

    [font=verdana,sans-serif]"An über-programmer is likely to be someone who stares quietly into space and then says 'Hmm. I think I've seen something like this before.'" -- John D. Cock[/font]

    opentu.net - freier, unzensierter Informationsaustausch via IRC-Channel!
    Hilfe und Support in Studienangelegenheiten, gemütliches Beisammensein, von und mit Leuten aus dem Informatik-Forum!

  • hab mich vor etwas laengerer Zeit relativ intensiv damit beschaeftigt, ein paar Gedanken dazu:

    ad Profiler) hab mit JProbe gearbeitet, ist echt ein nettes Tool und oft eine grosse Hilfe. Es gibt auch eine Trial Version (zumindest gabs die mal)

    ad GC) ich vermute Du verwendest die SUN VM (obwohl das Blackdown SDK dir glaub ich auch die Wahl laesst). Dann ist der GC default maessig ein Generationen Kollektor, und Du kannst mittels -XX:* VM Argumenten bezug auf die Groesse der neuen, alten, permanenten... Generationen nehmen. Um festzustellen, welche Einstellungen optimal sind, kannst Du den GC im verbose mode laufen lassen (-verbose:gc). Vorallem solltest Du aber verstehen, wie der GC arbeitet. Hendrik Schreibers 'Performant Java programmieren' (AW, ISBN: 3-8273-2003-8) ist recht interessant, ansonsten gibts genug papers auf citeseer.

    HTH

    this is Unix land. In silent nights, you can hear Windows machines reboot...

  • Zitat von hal

    wär mir neu, dass er sowas tut. eine schnelle google-recherche zeigt nur, dass es das problem der ungewollten referenz gibt (siehe zB hier), die aber technisch kein leak ist, sondern ein unfähiger programmierer ;).
    ansonsten sollte da nichts verloren gehen.

    kann ich mich nur anschließen ;)

    PS:
    1. so bekommt man viele posts !! ...... hehe
    2. klein schreiben sollte man vom programmieren her gewöhnt sein! (ich zumindest)

    mfg marX

  • Kann schon vorkommen, dass der GC was überlässt, was eigentlich gelöscht werden sollte. Kommt einfach drauf an, wie er den Memory scannt. Wenn er einfach alle 32 bit-Worte liest und als Pointer betrachtet, kann's ja schon mal zufällig passieren, dass ein solcher in einen Speicherbereich reinzeigt, der alloziert ist. V.a. wenn das Programm ein paar hundert MB braucht, ist das leicht möglich. Auf 64 bit-Maschinen passiert's klarerweise viel seltener, weil da schon einiges an Glück dazugehört, um mit einem wild zusammengewürfelten Pointer genau einen gültigen Speicherbereich zu treffen.

  • referenzen nicht von werten unterscheiden zu können würde unter die bereits besprochene "riesen bug im gc"-kategorie fallen, Java wär schon längst in der luft zerissen worden wenn das der fall wäre.

    [font=verdana,sans-serif]"An über-programmer is likely to be someone who stares quietly into space and then says 'Hmm. I think I've seen something like this before.'" -- John D. Cock[/font]

    opentu.net - freier, unzensierter Informationsaustausch via IRC-Channel!
    Hilfe und Support in Studienangelegenheiten, gemütliches Beisammensein, von und mit Leuten aus dem Informatik-Forum!

  • Zitat von Ringding

    Kann schon vorkommen, dass der GC was überlässt, was eigentlich gelöscht werden sollte. Kommt einfach drauf an, wie er den Memory scannt. Wenn er einfach alle 32 bit-Worte liest und als Pointer betrachtet, kann's ja schon mal zufällig passieren, dass ein solcher in einen Speicherbereich reinzeigt, der alloziert ist. V.a. wenn das Programm ein paar hundert MB braucht, ist das leicht möglich. Auf 64 bit-Maschinen passiert's klarerweise viel seltener, weil da schon einiges an Glück dazugehört, um mit einem wild zusammengewürfelten Pointer genau einen gültigen Speicherbereich zu treffen.

    1. zu "64-bit maschinen": da hast du anscheinend das prinzip von java noch nicht verstanden -> das übersetzte programm wird nicht direkt dem prozessor gefüttert, sondern einer virtuellen maschine -> der "maschinen-code" kann von keinem "normalen" pc-prozessor (nur von speziellen sun-prozessoren) direkt ausgeführt werden!! desshalb ist es auch egal ob di maschine 64 oder 32 bit hat -> die referenzen haben immer 64 bit (von der vm geregelt)

    2. also ich weiß ja nicht wie der gc den speicher verwaltet, aber er "scannt" sicher nicht den speicher (pach pointern) um auf referenzen zu prüfen !!! das wäre ja schon eine etwas hirnrissige methode !!
    java läuft ja auf einer virtuellen maschine (mit speziellen maschinen-codes) -> dies erlaubt es einer "kontrollierenden instanz" das kopieren einer referenz (pointer) zu verfolgen -> der referenz-counter wird incrementiert -> wenn der ref.count == 0 ist wird der speicherbereich freigegeben...

    ps: was vorher schon gesagt wurde: wenn java solche gravierenden fehler hätte wäre es niemals so "groß" geworden sondern gleich in der luft zerissen worden ;) (stell dir mal vor ein java programm würde auf einem handy oder organizer solche speicherprobleme verursachen!!)

    mfg marX

  • Zitat von marX

    der "maschinen-code" kann von keinem "normalen" pc-prozessor (nur von speziellen sun-prozessoren) direkt ausgeführt werden!!

    Nennt sich "Java Bytecode", und es gibt keine physikalischen Prozessoren, die das direkt ausführen können, ich glaub wegen der Komplexität (es waren mal welche in Planung, das wurde aber alles wieder verworfen).

    [font=verdana,sans-serif]"An über-programmer is likely to be someone who stares quietly into space and then says 'Hmm. I think I've seen something like this before.'" -- John D. Cock[/font]

    opentu.net - freier, unzensierter Informationsaustausch via IRC-Channel!
    Hilfe und Support in Studienangelegenheiten, gemütliches Beisammensein, von und mit Leuten aus dem Informatik-Forum!

  • Zitat von hal

    Nennt sich "Java Bytecode", und es gibt keine physikalischen Prozessoren, die das direkt ausführen können, ich glaub wegen der Komplexität (es waren mal welche in Planung, das wurde aber alles wieder verworfen).

    Soweit ich weiss werden die meisten neueren handies mit java-optimierten prozessoren ausgeliefert.

    Es fragt sich natürlich, was man hier wirklich unter 'optimiert' versteht, aber angeblich wurden 2003 mehr java optimierte prozessoren verkauft als intel modelle.

    ich hab die quelle leider verschlampt (ich glaub das war ein slashdot artikel), ich suche aber weiter.

  • Du, ich weiß, was eine Java VM macht, ich arbeite nämlich an einer im Rahmen meiner Diplomarbeit. Und der Boehm GC, ein sehr weit verbreiteter Garbage Collector, tut genau das, was ich beschrieben habe, nämlich den Speicher scannen. Außerdem haben die Pointer auf einer 32bit-Maschine natürlich 32 Bit und nicht 64.

  • Zitat von Ringding

    Du, ich weiß, was eine Java VM macht, ich arbeite nämlich an einer im Rahmen meiner Diplomarbeit. Und der Boehm GC, ein sehr weit verbreiteter Garbage Collector, tut genau das, was ich beschrieben habe, nämlich den Speicher scannen. Außerdem haben die Pointer auf einer 32bit-Maschine natürlich 32 Bit und nicht 64.

    1. also dann ist dieser gc aber nicht speziell für java entwickelt, sonst wäre es nämlich nicht umbedingt zweckmäßig ein so umständliches (und fehlerbehaftetes) verfahren zu wählen, wenn das programm sowieso emuliert werden muss.....

    2. meinses wissens haben referenzen in java (VM-intern) immer 64 bit !
    (wäre zumindest sinnvoll....in hinblick auf kompatibilität)

    mfg marX

  • Zitat von marX

    ... ein so umständliches (und fehlerbehaftetes) verfahren zu wählen...

    naja, fehlerhaft isses denk ich nicht: Speicher scannen, alle allokierten Speicherbereiche, die nicht potenziell referenziert werden deallokieren (so habs ich zumindest verstanden). Ok, es bleibt wahrscheinlich auch was im Speicher, was eigentlich gelöscht werden könnte, aber wenn man bedenkt, dass die meisten Programme mit wenigen MB auskommen (und sich daher der Aufwand in Grenzen hält), isses eigentlich nicht so blöd.

    Why bother spending time reading up on things? Everybody's an authority, in a free land.

  • Richtig, solange sich der allozierte Speicher in Grenzen hält, ist das sehr brauchbar. Für große Speichermengen empfiehlt sich halt dann doch ein größerer Addressraum, sprich 64 Bit-Maschinen.

    Btw, der Boehm GC wird z.B. von GCJ (GNU Java Compiler), GNU Objective C, Mozilla und Mono verwendet und funktioniert dort offenbar ausgezeichnet.

  • Zitat von Ringding

    Btw, der Boehm GC wird z.B. von GCJ (GNU Java Compiler), GNU Objective C, Mozilla und Mono verwendet

    hm... ich kenn mich von dieser liste nur in objective c etwas genauer aus, und ich bin mir sicher, dass dort praktisch nur reference counting verwendet wird. den boehm gc gibts zwar, aber den verwendet niemand in produktion.

    [font=verdana,sans-serif]"An über-programmer is likely to be someone who stares quietly into space and then says 'Hmm. I think I've seen something like this before.'" -- John D. Cock[/font]

    opentu.net - freier, unzensierter Informationsaustausch via IRC-Channel!
    Hilfe und Support in Studienangelegenheiten, gemütliches Beisammensein, von und mit Leuten aus dem Informatik-Forum!

  • Zitat von Ringding

    Richtig, solange sich der allozierte Speicher in Grenzen hält, ist das sehr brauchbar. Für große Speichermengen empfiehlt sich halt dann doch ein größerer Addressraum, sprich 64 Bit-Maschinen.

    klar funktionierts (prinzipiell) aber warum sollte man wenn man ja eh eine virtuelle maschine hat und somit das kopieren von referenzen überwachen kann, nicht eine "sauberere" methode wählen ?!! (wäre nicht viel langsamer, aber viel sauberer bzw. gründlicher)

    -> für c/c++ bzw andere programmiersprachen ohne vm (oder emulation) kann natürlich nur ein speicher-scann-verfahren verwendet werden...

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!