Ich arbeite gerade daran, meine Anwendung zu optimieren, und mir ist aufgefallen, dass sie fast 1 GB Arbeitsspeicher beansprucht. Ich habe ein Profiling gemacht und das Problem gefunden: Ich habe viel Speicher reserviert, indem ich int-Arrays erstellt habe, die Pixeldaten in einer von mir erstellten Texturklasse enthalten. Aber das verwirrt mich, denn wenn man ein neues Array erstellt, wird das alte Array nicht mehr benutzt und es gibt keinen Bezug mehr.Java - nicht referenzierte Arrays nehmen immer noch Speicher auf
Ich habe ein Testprogramm geschrieben, das dieses Problem reproduziert:
public class Main {
static class ArrayHolder {
int[] array;
void init() {
array = null;
array = new int[4000];
}
}
public static void main(String[] args) {
ArrayHolder holder = new ArrayHolder();
for (int i = 0; i < 1000000; i++) {
holder.init();
}
System.out.println(holder.array.length);
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Wenn ich diesen Code ausführen verwendet das Programm bis 600 Megabyte RAM. Ich verstehe nicht, warum, weil beim Aufrufen der Methode init() in ArrayHolder das Array-Feld auf das neue Array festgelegt wird und der Verweis auf den alten verloren geht. Würde das nicht bedeuten, dass es keinen Platz mehr einnimmt? Es tut mir leid, wenn das eine noobish Frage ist, aber kann jemand erklären, warum das ist und was ich hier falsch mache?
Ihr altes Array würde nur im Ermessen von GC gestartet werden. Wenn GC bald nach der Neuzuweisung von Speicher ausgeführt wird, wird der Speicherplatz zurückgewonnen, andernfalls wird er nicht verwendet. – SMA
große Arrays werden zum festen Speicherplatz hinzugefügt und dies wird standardmäßig nur GC-ed, wenn es voll ist. z.B. Schlafen löst keinen GC aus. Kurz gesagt, ist es aus so vielen Gründen schlecht, so viele große Arrays zu erstellen. –