Я немного экспериментирую с Java и способностью утечки памяти. Я написал этот простой код:Java: странная ошибка утечки памяти со списками
import java.util.ArrayList;
import java.util.List;
public class Test {
public static void main(String[] args) {
class Obj {
int i;
Obj(int i) {
this.i = i;
}
}
List<Obj> list;
while(true) {
list = new ArrayList<Obj>();
for(int i = 0; i < 1000; i++) {
Obj o = new Obj(i);
list.add(o);
}
try {
Thread.sleep(1); //<-- added to give the gc time to trash the previous iteration
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Когда это будет выполнено (особенно с большим количеством объектов, которые добавляются в список каждой итерации), вы можете посмотреть объем памяти, используемый для увеличения быстро. Я смог быстро ударить 2 гигабайта с добавлением 10000 объектов на каждой итерации. Казалось бы, списки (и другие типы объектов, которые используют список связанных списков, таких как функция) не любят удаляться.
Когда я не добавил объекты в список, куча памяти не увеличилась вообще (что означает удаление мусора, выполняющее свою работу). Я попробовал сбросить список до нуля на каждую итерацию, а затем повторно объявить ее, а также вызвать метод clear(). Ничто не работает. Всякий раз, когда я использую List в цикле, моя RAM кричит о помощи.
Итак, почему это происходит? Почему избавление от мусора не избавляет от списка каждую итерацию, а не позволяет им складываться? Разве интерфейс List не позволяет использовать этот вид? Неужели я просто не даю мусорному убору достаточно времени, чтобы избавиться от последней инстанции?
Примечание: 'Thread.sleep (1)' спит в течение 1 миллисекунды, а не 1 секунду. –
Да, я знаю. Я тоже пробовал с большей продолжительностью. – CoderTheTyler
Используйте 'System.gc()' для запуска сборки мусора. сон не делает трюка. Более того, «list» по-прежнему ссылается на текущий фрейм функции, поэтому его нельзя собирать. – kan