2016-11-28 2 views
0

BlueJ의 Java 힙 공간에 문제점이 있습니다. .txt를 String으로 읽고 문자열의 모든 문자를 처리하고 몇 가지 작업을하는 프로그램을 작성했습니다 (이것이 중요하지 않음). .txt의 일부는 실제로 크기가 큽니다 (약 2 억 개). 이러한 .txt로 프로그램을 실행하려고하면이 "예외 스레드"AWT-EventQueue-0 "java.lang.OutOfMemoryError : Java 힙 공간"오류 코드가 발생합니다. 나는 bluej.define의 bluej.windows.vm.args와 bluej.windows.vm.args를 8GB로 늘렸다. 그리고 여전히 작동하지 않습니다. 하지만 실제로는 2 억 개의 문자열까지도이 한도를 초과하지 않을 것이라고 생각합니다. 는 여기가 .txt 인BlueJ의 Java 힙 공간

try 
    { 
     FileReader reader = new FileReader(input.getText()); 
     BufferedReader bReader = new BufferedReader(reader); 
     String parcour = ""; 
     String line = bReader.readLine(); 
     while(line != null) 
     { 
      parcour += line; 
      line = bReader.readLine();    
     } 

input.getText() 파일 경로를 얻을 읽을 어떻게 내 코드입니다. 답변에 정말 감사 할 것입니다. 감사합니다 :) - Cyaena

+1

전체 파일을'parcour' 변수에 저장합니다. 이것은 많은 기억을 먹을 것입니다. 또한, 문자열에 데이터를 추가 할 때'StringBuilder'를 사용하는 것을 고려하십시오. – ar34z

+0

하지만 실제로 문자열은 많은 메모리를 먹어서는 안됩니다. 그렇습니까? StringBuilder를 사용하면 어떤 이점이 있습니까? 그리고 대략 어떻게 설정합니까? – Cyaena

+1

저는 메모리 사용법을 설명하는 사람이 아니지만 200mil을 저장하고 있습니다. 기억 속의 인물들은별로 유망하지 않다. 루프에서 문자열을 연결하면 'StringBuilder'가 더 빠릅니다. 2 억 라인으로 무엇을하려하고 있습니까? 아마도 이것은 당신을 도울 수 있습니다 : http://stackoverflow.com/questions/10202905/is-it-advisable-to-store-large-strings-in-memory-or-repeatedly-read-a-file 메모리 사용에 대한 더 많은 정보 : http://www.javamex.com/tutorials/memory/string_memory_usage.shtml – ar34z

답변

0

아래의 설명에서 데이터에 대한 일반 메모리 만 범위에 있습니다. 구조체에 대한 모든 추가 메모리 필요가 없어집니다. 세부적인면에서 볼 때 개요입니다.

메모리가 그 라인을

String parcour = ""; 
... 
String line = bReader.readLine(); 
... 
parcour += line; 

라인 parcour += line에 먹는 parcour 가정

new StringBuilder().append(parcour).append(line).toString() 

으로 클래스 파일로 컴파일 크기가 10MB로 문자열을 포함하고 line 크기의 것입니다 2 MB. 새로 만들어진 문자열이 parcour (34) 주위 MB에 할당하기 전에 다음 parcour += line; 동안 할당 된 메모리가 될 것이다 (대략)

// creates a StringBuilder object of size 12 MB 
new StringBuilder().append(parcour).append(line) 

// the `.toString()` would generate a String object of size 12 MB 
new StringBuilder().append(parcour).append(line).toString() 

코드는 필요합니다.

parcour       = 10 MB 
the temporary StringBuilder object = 12 MB 
the String fromStringBuilder  = 12 MB 
------------------------------------------ 
total        34 MB 

작은 데모 조각

OutOfMemoryException이 훨씬 이전에 현재 기대 후 발생 된 것입니다.

OOMString.java

class OOMString { 
    public static void main(String[] args) throws Exception { 
     String parcour = ""; 
     char[] chars = new char[1_000]; 
     String line = new String(chars); 
     while(line != null) 
     { 
      System.out.println("length = " + parcour.length()); 
      parcour += line; 
     }   
    } 
} 

OOMStringBuilder.java

class OOMStringBuilder { 
    public static void main(String[] args) throws Exception { 
     StringBuilder parcour = new StringBuilder(); 
     char[] chars = new char[1_000]; 
     String line = new String(chars); 
     while(line != null) 
     { 
      System.out.println("length = " + parcour.length()); 
      parcour.append(line); 
     }   
    } 
} 

두 조각이 동일한 않습니다. 그들은 OutOfMemoryException이 던져 질 때까지 parcour에 1,000 자 문자열을 추가합니다. 속도를 높이기 위해 힙 크기를 10MB로 제한합니다. 코드를 실행하면 java -Xmx10m OOMString

length = 1048000 
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space 

출력

length = 2052000 
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space 

java -Xmx10m OOMStringBuilder의의

출력 당신은 OOMString 요구에 훨씬 더 많은 시간이 OOMStringBuilder보다 (심지어 짧은 길이에) 실패하는 것을 알 수 있습니다.

단일 문자는 2 바이트 길이라는 점을 명심해야합니다.파일에 ASCII 문자 100 개가 포함되어 있으면 메모리에서 200 바이트를 소비합니다.

아마도이 작은 데모가 당신에게 조금 설명 할 수 있습니다.

0

BlueJ 및 힙 공간 오류에도 몇 가지 문제가있었습니다. 제 경우에는 터미널을 열면 전체 응용 프로그램이 손상되었습니다. 나는 이것이 당신의 커다란 String과 비슷한 많은 출력을 생성하는 것과 관련이 있다고 생각한다. 제 경우에는 실수로 터미널 창을 어딘가에 끝없는 루프를 만들었습니다.

모든 속성 파일을 제거해야했습니다. 이제 BlueJ가 다시 작동하고 더 이상 OutOfMemoryErrors를 제공하지 않습니다. 다른 경우에도 도움이되기를 바랍니다.