Ich bin der Meinung, dass man auch in Java sehr wohl Memory Leaks erzeugen kann. Wikipedia schreibt dazu (Link):
Das ist genau der Fall, der hier auftritt: Logisch gesehen wurde das Objekt bereits aus unserem DynamicArray entfernt, trotzdem befindet sich in theArray noch eine nicht mehr benötigte Referenz (obsolete reference) auf das Objekt, die verhindert, dass der Garbage Collector seine Arbeit tut.Falls die verwendete Laufzeitumgebung eine automatische Speicherbereinigung bereitstellt, versucht diese zu ermitteln, auf welche Speicherbereiche ein Prozess nicht mehr zugreift. Stellt die Laufzeitumgebung fest, dass ein belegter Speicherbereich für das Programm nicht mehr erreichbar ist, wird dieser wieder freigegeben. Nicht mehr erreichbar heißt in diesem Zusammenhang, dass keine gültige Referenz auf den belegten Speicherbereich mehr existiert. Speicherlecks können dabei dennoch entstehen, wenn der Speicher für das Programm noch erreichbar ist, d. h. es eine Referenz auf den Speicher hält, ihn aber dennoch nicht mehr verwendet.
Je nach Größe der in dem Array gespeicherten Objekte kann dies fatale Auswirkungen auf die Performanz bzw. den Speicherverbrauch des Programms haben. Hier ein Beispiel dazu:
Code: Alles auswählen
public int scrapePage(String url) {
List<String> interestingLinks = new ArrayList<>();
DynamicArray<byte[]> caches = new DynamicArray<byte[]>(10);
for (int i = 0; i < 10; i++) caches.insert(new byte[100_000_000], i);
// ...
// Sehr komplizierter Code, der die Webseite aufruft (und dafür
// das Cache-Array benötigt) und die Liste mit Links befüllt.
// ...
for (int i = 10 - 1; i >= 0; i--) caches.remove(i);
int score = 0;
for (String link : interestingLinks)
score += scrapePage(link);
return score;
}
Um diese Probleme zu vermeiden, sorgen wir einfach dafür, dass alle Zellen von theArray mit einem Index >= currentNumberOfElements den Wert null enthalten:
Code: Alles auswählen
public void remove(int position) {
for (int i = position; i < currentNumberOfElems - 1; i++)
theArray[i] = theArray[i + 1];
theArray[currentNumberOfElems - 1] = null;
currentNumberOfElems--;
}
Auch dort wird empfohlen "null out references once they become obsolete" und "whenever a class manages it own memory, the programmer should be alert for memory leaks". (Das ist hier in der Tat der Fall, da wir nur einen Teil des Array-Speichers benutzen.)