2012-12-07 16 views
6

Próbuję odczytać plik txt 2,5 GB do mojej aplikacji. Używam Win7 x64 i mam dostępne 43 GB pamięci (z 64 GB). Próbowałem odtwarzać z opcją -Xmx -XX: MaxParmSize -XX: ParmSize itp. Żadne z tych nie wpływa na błąd. Co jeszcze mogę spróbować? Ten błąd wydaje się bardzo dziwny, ponieważ na pewno mam wystarczająco dużo miejsca na sterty.java.lang.OutOfMemoryError pomimo dużej ilości

Exception in thread "main" java.lang.OutOfMemoryError: Requested array size exceeds VM limit 
    at java.util.Arrays.copyOf(Unknown Source) 
    at java.lang.AbstractStringBuilder.expandCapacity(Unknown Source) 
    at java.lang.AbstractStringBuilder.ensureCapacityInternal(Unknown Source) 
    at java.lang.AbstractStringBuilder.append(Unknown Source) 
    at java.lang.StringBuilder.append(Unknown Source) 
    at j.utilities.IO.loadString(IO.java:187) 
    at j.utilities.IO.loadString(IO.java:169) 
    at city.PreProcess.main(PreProcess.java:78) 

Używam

java version "1.7.0_09" 
Java(TM) SE Runtime Environment (build 1.7.0_09-b05) 
Java HotSpot(TM) 64-Bit Server VM (build 23.5-b02, mixed mode) 

Bardzo dziękuję z góry.

============== ODPOWIEDŹ ==============

OK, ja tylko testowałem to z

StringBuilder sb = new StringBuilder(); 
for (int i=1; i<Integer.MAX_VALUE; i++) 
    sb.append("x"); 

i dostał

Exception in thread "main" java.lang.OutOfMemoryError: Requested array size exceeds VM limit 
at java.util.Arrays.copyOf(Unknown Source) 
... 

ten sposób, to naprawdę jest StringBuilder który próbuje zbudować tablicę większy niż Integer.MAX_VALUE.

W przypadku zainteresowanych

StringBuilder sb = new StringBuilder(); 
int i=1; 
try { 
    for (; i<Integer.MAX_VALUE; i++) 
     sb.append("x"); 
} catch (OutOfMemoryError e) { 
    System.out.println(i); // OUTPUT: 1207959551 
    System.out.println(Integer.MAX_VALUE); // OUTPUT: 2147483647 
} 

Z StringBuilder można gromadzić 1,207,959,550 znaki - znacznie mniej niż Integer.MAX_VALUE.

+0

Wygląda na to, że próbujesz przydzielić tablicę. Ile elementów ma tablica? – reprogrammer

+0

Co to jest kod w 'PreProcess.java: 78'? –

+0

Co to jest "j.utilities.IO"? Jeśli to twój kod wklej "IO.java: 169". –

Odpowiedz

8

Próbujesz przydzielić tablicę, która jest zbyt duża. Dzieje się tak, ponieważ próbujesz utworzyć bardzo długi ciąg. Ponieważ tablice są indeksowane przez liczbę całkowitą, tablica nie może mieć więcej niż Integer.MAX_VALUE elementów. Nawet jeśli twój rozmiar sterty jest bardzo duży, nie będziesz mógł przydzielić tablicy, która ma więcej niż Integer.MAX_VALUE elementów, po prostu dlatego, że nie możesz indeksować jej elementów za pomocą Integer. Aby uzyskać więcej informacji, patrz Do Java arrays have a maximum size?.

+0

Czy StringBuilder wewnętrznie korzysta z tablicy? A może to, że ciąg jest interpretowany jako tablica znaków? – dotwin

+0

Powinien zawierać "char []". – reprogrammer

+2

Tak StringBuffer/StringBuilder przechowuje swoje dane w tablicy. Ale jeśli masz łańcuch większy niż 2 GB, to robisz coś złego. \ – MTilsted

0

Powinieneś zajrzeć do opcji -Xmsn dla polecenia java.

Określa początkowy rozmiar puli alokacji pamięci.

Edytuj: Widzę, że już to zrobiłeś.

2

Można utworzyć nowy StringBuilder o wielkości, np.

StringBuilder sb = new StringBuilder(Integer.MAX_VALUE); 

Problemem jest to, że starasz się odczytać plik, który jest większy niż to, co StringBuilder może mieć w swojej tablicy. Masz kilka opcji, np .:

1) Czy na pewno chcesz od razu przeczytać cały plik w pamięci? Jeśli tak, będziesz musiał przeczytać go na kilku StringBuilders.

2) Przetwarzaj plik sekwencyjnie.

3) Odczytaj skompresowaną strukturę i rozpakuj potrzebne części, gdy ich potrzebujesz.

0

Można przechowywać dane w danych bufora żądła jest Lista w zdefiniowanym przedziale i wyczyść StringBuffer. mam nadzieję, że to ci pomoże. daj mi znać, jeśli wymagane są dodatkowe szczegóły.

Powiązane problemy