Spróbuj przepisanie kodu w następujący sposób i nie należy się OOME w ...
Random r = new Random(1234697890);
HashMap<Integer, List<Integer>> map = new HashMap<Integer, List<Integer>>();
for(int i=0;i<100000;i++){
List<Integer> list = new ArrayList<Integer>();
for(int j=0;j<1000;j++){
list.add(r.nextInt(100000));
}
map.put(i, list);
map.remove(i);
}
Problem z oryginalnego kodu jest to, że:
- utworzyć tylko jedną listę,
- dodajesz do niego coraz więcej elementów, a lista kończy się tylko śmieciami, gdy kod zostanie ukończony ... ponieważ cały czas jest "w zasięgu".
Moving deklarację wewnątrz pętli list
oznacza, że nowy ArrayList
jest tworzony i wypełnione w każdej iteracji pętli, a staje się śmieci po uruchomieniu kolejnej iteracji.
Ktoś zasugerował dzwoniąc pod numer System.gc()
. Nie pomoże to w twoim przypadku, ponieważ do zebrania śmieci jest niewiele. A w ogóle to jest to zły pomysł, ponieważ:
- GC jest zagwarantowane, że prowadzony bezpośrednio przed OOME jest wyrzucane,
- JVM może dowiedzieć się lepiej niż można, gdy jest to najlepszy (czyli najbardziej wydajny) czas na uruchomienie GC,
- Twój telefon do
System.gc()
może i tak zostać całkowicie zignorowany. JVM można skonfigurować tak, aby połączenia z numerem System.gc()
były ignorowane.
1 - The pedant we mnie pragnie podkreślić, że map.put(i, list); map.remove(i);
najprawdopodobniej generowania Integer
obiektu, który najprawdopodobniej stanie się śmieci. Jednak jest to "karma dla kurcząt" w porównaniu do twojego nieskończenie rosnącego obiektu .
Zawsze dodajesz do listy i nigdy nie usuwasz z niej. –
FYI, guava ma zestaw "Multimap", który implementuje 'Mapę>' i dba o tworzenie list dla ciebie. –
@JohnB - jak to może mieć znaczenie dla pytania? – Perception