2010-03-12 6 views
6

이 메서드를 호출하면 java outOfMemoryError가 발생합니다. 루프에서이를 사용하여 많은 큰 파일을 순차적으로 파싱합니다. 내 생각 엔 result.toString()은 루프 중에 제대로 가비지 수집되지 않습니다. 그렇다면 어떻게 수정해야합니까?java outOfMemoryError with stringbuilder

private String matchHelper(String buffer, String regex, String method){ 
    Pattern abbrev_p = Pattern.compile(regex);//norms U.S.A., B.S., PH.D, PH.D. 
    Matcher abbrev_matcher = abbrev_p.matcher(buffer); 
    StringBuffer result = new StringBuffer(); 
    while (abbrev_matcher.find()){ 
      abbrev_matcher.appendReplacement(result, abbrevHelper(abbrev_matcher)); 
    } 
    abbrev_matcher.appendTail(result); 
    String tempResult = result.toString(); //ERROR OCCURS HERE 
    return tempResult; 

} 
+2

는 "큰 파일은"얼마나 큰 :

는 고정 및 텍스트를 추가하기위한 링크를 권장? JVM에 충분한 메모리를 할당하지 않은 것일 수도 있습니다. – Ash

+0

추가 조사를 위해 오류 텍스트를 표시하십시오. – Artic

+0

의 순수한 문자열은 어떻습니까? OString Length : 2769348? 대부분의 문자열은 캡처 한 사진의 nexString입니다. –

답변

6

이렇게 작성하면 파일의 모든 문자에 약 바이트의 메모리가 필요합니다.

각 문자는 2 바이트입니다. 원시 입력, 대체 된 출력 (버퍼에 있음)이 있으며 메모리가 부족할 때 세 번째 사본을 요청합니다.

파일이 ASCII 또는 ISO-8859-1 (1 바이트 문자 인코딩)로 인코딩 된 경우 이는 디스크보다 메모리가 6 배 더 커짐을 의미합니다.

프로세스에 더 많은 메모리를 할당 할 수 있지만 "스트림 방식"으로 입력을 처리하는 것이 더 나은 해결책 일 수 있습니다. — 데이터를 모두 메모리에 한 번에로드하지 않고 읽고, 스캔하고 쓸 수 있습니다.

+1

위로 엄지 손가락. 여러분의 프로세싱이 라인 단위 작업에 기반한 것이라면 다음과 같이하면됩니다 :'BufferedReader rd = new BufferedReader (new FileReader ("/ path/to/your/file"));'readLine ()'while 루프에서, 바꾸기를 수행하고 변경된 라인에 필요한 것을 수행하십시오. – dimitarvp

0

당신은 StringBuffer를 반환하고 사용 후 null로 설정 시도 할 수 있습니다.

2

처리 할 파일이 모두 매우 크고 수백 메가 바이트 이상이라면 @erickson이 제안한 것처럼 "모든 것을 메모리에로드"하는 대신 스트림 처리를 수행해야합니다.

그렇지 않으면, 당신이 시도 할 수있는 몇 가지가 모두 가능한 한 많은 메모리 사용량을 줄일 수있다 :

  1. 제대로하지 않을 경우 아직 힙 크기를 확대 해보십시오 (해당되는 경우).
  2. Stringbuffer의 길이와 동일한 초기 크기를 StringBuffer에게 지정하십시오. 이 과정에서 StringBuffer을 확장하는 동안 불필요한 메모리 사용을 줄여야합니다. 나는 그것이 원래의 문자열의 특정 단어만을 대체하고 길이는 같거나 적어야한다고 가정한다.
  3. 가능한 경우 생성 된 StringBuffer 개체를 대신 반환 할 수 있습니다. 원래 String 객체를 제거한 후에 만 ​​toString()을 호출합니다. 예외가 반드시이 문제의 의미하지 가 않습니다 발생 간단하기 때문에
+0

힙 크기를 늘리십시오. –

1

나는 ... 다른 답변에 동의 ...하지만. 다른 곳에서는 leaking memory 일 가능성이 높으며 공개 된 곳이기도합니다. profiler을 실행하여 메모리 사용을 검사하고 어떤 개체가 수집되고 있지 않은지 정확하게 확인해야합니다.

1

이 문제는 StringBuilder.append()으로 생각합니다. Matcher가 일련의 문자를 빌더에 추가 할 때.

OutOfMemoryError with StringBuilder/StringBuffer에 설명 된 것처럼 용량이 충분하지 않은 경우 append()가 내부 버퍼 chars 인 경우 용량을 두 배로 늘리는 것이 알려진 문제입니다. Erickson에서 제안한대로 이동하십시오.