Speicherleck



  • Aus Speicherleck#Automatische_Speicherbereinigung_2 (Wiki):

    public void erzeugeSpeicherleck() {
      List<Integer> nummern = new ArrayList<>();
      for (int i=1; i<10000; i++)
        nummern.add(i);
    }
    

    ... das leckt doch nicht wirklich, oder? Soweit ich Java verstanden habe, wird nummern (und auch alle davon exklusiv gehaltenen Referenzen) doch zum Abschuss durch den GC freigegeben, sobald es out of scope geht!?



  • Das Beispiel war mal anders: http://de.wikipedia.org/w/index.php?title=Speicherleck&diff=111358940&oldid=111356653

    Zwar auch nicht sonderlich sinnvoll, aber immerhin hat das Programm über nennenswerte Zeit Speicher verschwendet. Im Moment ist es totaler Schwachsinn. Das kanonische Beispiel für Speicherlecks trotz GC dürfte eine globale/statische Liste/Hashtable o.ä. sein, von der nicht mehr alle Einträge gebraucht werden.



  • Bashar schrieb:

    Das Beispiel war mal anders: http://de.wikipedia.org/w/index.php?title=Speicherleck&diff=111358940&oldid=111356653
    Zwar auch nicht sonderlich sinnvoll, aber immerhin hat das Programm über nennenswerte Zeit Speicher verschwendet.

    Für mich auch kein Speicherleck, denn der Programmierer könnte ja wann und wo er wollte a.CLEAR() oder a.REMOVE(i) machen.

    Bashar schrieb:

    Im Moment ist es totaler Schwachsinn.

    Danke, mein Weltbild ist gerettet. 👍

    Bashar schrieb:

    Das kanonische Beispiel für Speicherlecks trotz GC dürfte eine globale/statische Liste/Hashtable o.ä. sein, von der nicht mehr alle Einträge gebraucht werden.

    Hm. "von der nicht mehr alle Einträge gebraucht werden" hört sich für mich so an, als ob der Algorithmus irgendwie (Objekteigenschaften des Eintrags, Key oder Index des Eintrags) irgendwann in seiner Laufzeit feststellen können müßte, daß sie nicht mehr für die weitere Ausführung gebraucht werden? Damit wäre auch die Möglichkeit gegeben, sie zu entsorgen. Im Vergleich dazu:

    void * mem = malloc( 42 );
    mem = NULL;  // Speicherleck! Der zuvor angeforderte Speicher *kann nicht* freigegeben werden.
    

    ?



  • Hm. "von der nicht mehr alle Einträge gebraucht werden" hört sich für mich so an, als ob der Algorithmus irgendwie (Objekteigenschaften des Eintrags, Key oder Index des Eintrags) irgendwann in seiner Laufzeit feststellen können müßte, daß sie nicht mehr für die weitere Ausführung gebraucht werden? Damit wäre auch die Möglichkeit gegeben, sie zu entsorgen.

    Wenn du mit Algorithmus die GC meinst, dann: Nein!

    Damit wäre auch die Möglichkeit gegeben, sie zu entsorgen. Im Vergleich dazu:

    Ja, die Möglichkeit ist gegeben. Aber der Effekt ist schlimmstenfalls der gleiche. Mit der Zeit verbraucht dein Programm immer mehr und mehr Speicher, irgendwann wird ausgelagert und dann irgendwann gibts OutOfMemory-Exceptions. Ich hab die Erfahrung gemacht, dass dieser Effekt häufig im Zusammenhang mit Listenern auftritt, welche in irgendeiner Liste weiterexistieren, obwohl sie nicht mehr gebraucht werden.

    Hier ist eine gute Quelle dazu: http://www.gruntz.ch/courses/sem/ss02/leaks.pdf

    LG



  • mmazal schrieb:

    Hm. "von der nicht mehr alle Einträge gebraucht werden" hört sich für mich so an, als ob der Algorithmus irgendwie (Objekteigenschaften des Eintrags, Key oder Index des Eintrags) irgendwann in seiner Laufzeit feststellen können müßte, daß sie nicht mehr für die weitere Ausführung gebraucht werden? Damit wäre auch die Möglichkeit gegeben, sie zu entsorgen.

    Wenn du mit Algorithmus die GC meinst, dann: Nein!

    Ich meine das Programm. Auf die Runtime hat der Entwickler in dieser Hinsicht ja keinen Einfluss.

    Die eigentliche Frage, die ich nun habe ist: Was ist ein Speicherleck?

    Ist es Speicher, der während der Laufzeit nicht mehr freigegeben werden kann?
    Ist es Speicher, der vom Algorithmus nicht freigegeben wird, obwohl die Möglichkeit weiterhin bestünde?

    Ich tendiere zu ersterem. Zweites ist einfach eine bescheuerte Implementierung.



  • Außerhalb von Wikipedia-Pedanterien ist das doch völlig belanglos.



  • Mich interessierts, wie die landläufige Meinung ist!?



  • Ich seh den Unterschied jetzt nicht wirklich. Wenn du in C Speicher nicht freigibst und den nicht mehr freigeben kannst, weil du den Zeiger nicht mehr hast, ist es ja trotzdem dein Fehler. Genauso wenn du in Java clear nicht aufgerufen hast.



  • Das Objekt nummern und dessen Inhalt sollte doch nach verlassen der Methode erzeugeSpeicherleck vom GC automatisch irgendwann freigegeben werden? Es wird ja keine Referenz auf das Objekt zurückgegeben und behalten. Daher müsste es doch egal sein wie oft ich die Methode aufrufe solange der Speicher reicht und der GC hinterher kommt. Also ich sehe da jetzt auch kein Speicherleck, nur eine schwachsinnige Implementierung.

    Gruß, Daniel_S



  • Danke Daniel, aber diese Frage ist schon lange geklärt.