Memory Leaks



  • Stimmt es eigentlich, dass der GC sowas nicht aufräumen kann?

    class Mem {
    		public Mem other;
    	}
    
    ...
    
    	Mem a = new Mem();
    	Mem b = new Mem();
    	a.other = b;
    	b.other = a;
    	a = null;
    	b = null;
    

    Oder kann der GC erkennen, dass die sich nur gegenseitig referenzieren und es keinen weg zu ihnen mehr gibt und das dann aufräumen?



  • Wird natürlich entfernt.



  • So natürlich finde ich das nicht. a wird ja immer noch von b referenziert und b von a, so kann der GC nicht einfach erkannen, dass die nicht mehr verwendet werden.


  • Mod

    BeastieBeast schrieb:

    So natürlich finde ich das nicht. a wird ja immer noch von b referenziert und b von a, so kann der GC nicht einfach erkannen, dass die nicht mehr verwendet werden.

    Die GCs von Java kommen mit zyklischen Referenzen zurecht. Kannst es ja mal ausprobieren:

    Mach 1.000.000.000 mal

    1. Erzeuge so ein Paar, das sich gegenseitig referenziert.
    2. Lösche alle externern Referenzen auf dieses Paar.

    Wenn Du dafür genug Speicher hast, dann löscht der GC offensichtlich alles.



  • Bis zu welcher Tiefe? Geht das auch noch, wenn ich nen Zyklus über 10, 100 oder 1000 Objekte mache (a->b->c->d->e->...->z->a)? Ist das eigentlich irgendwo definiert was so ein GC können muss oder kann sich das je nach Implementierung unterscheiden?



  • BeastieBeast schrieb:

    So natürlich finde ich das nicht. a wird ja immer noch von b referenziert und b von a, so kann der GC nicht einfach erkannen, dass die nicht mehr verwendet werden.

    doch, das kann er ganz leicht erkennen. mit deiner zyklischen definition hast du jeweils zwei "referenzierungspfade" für die objekte erstellt. "a = null" sorgt dafür, dass ein pfad auf a verschwindet. nach "b = null" verschwindet ein pfad auf b, zeitgleich der zweite auf a und somit auch der zweite auf b. zyklische referenzen sind keine magie.

    soweit ich weiss, muss der GC einer jvm implementierung garantieren, dass nicht-referenzierte objekte erkannt und der speicher freigegeben wird.
    allerdings wird nicht garantiert, dass dies auch immer sofort geschieht. es kann also durchaus passieren, dass der heap überläuft und die jvm absemmelt, wenn man zu schnell, zuviele objekte erzeugt und wieder verwirft.



  • Der GC macht ne Full Collection über alle Live Objects, bevor ein Programm mit ner Heap Size Exception abraucht.


Anmelden zum Antworten