outOfMemory StringBuffer 에서
봄나
약 30 메가정도 되는 텍스트 파일을 읽어 들여서 라인별 패턴매칭여부를 검사하고 검사에서 부적격한 라인들은 StringBuffer 에 append 한후 JTextArea 에 toString();하는 간단한 코드입니다.
30메가 전부가 패턴에 매칭되지않았다고 가정하고 모든 라인(약 70만개정도 되더군요 ㅜ) 을 StringBuffer 에 append 시켜보았씁니다.
그 결과 outOfMemory exception 이 발생 하더군요 ....
검색결과 heap 메모리를 최대최소 지정을 하는 옵션을 쓰라고 하시던데...
그것보다 아래 코드에서 메모리릭 이 발생한건지 알고 싶습니다. 아무래도 루프돌면서 StringBuffer에서 생기는건 확실한데
그렇다면 이 문제를 해결할수없는건가요?
fr=newFileReader(path);
br=newBufferedReader(fr);
Stringline=;
HDicCheck.this.errEditArea.setText();
StringBuffersb=newStringBuffer();
while((line=br.readLine())!=null){
if(!line.matches(patternString)){
sb.append(line).append(\n);
errLines++;
}
totalLines++;
}//endofwhile
if(0!=sb.length()){
HDicCheck.this.errEditArea.setText(sb.toString());
HDicCheck.this.isEditable=true;
HDicCheck.this.errEditArea.setEditable(HDicCheck.this.isEditable);
}
sb=newStringBuffer();
sb.append(파일:).append(path).append(\n);
sb.append(총라인:).append(String.valueOf(totalLines)).append(\n);
sb.append(오류라인:).append(String.valueOf(errLines)).append(\n);
sb.append(매치패턴:).append(patternString).append(\n);
-
동이
메모장에서 30메가의 파일을 받아낼 수 있는 것은 메모리맵을 사용하기 때문입니다. 처리할 파일이 30메가라 하더라도 메모리에 적재 되는 것은 30메가 전부가 아닌 현재 메모장에 표시되고 있는 부분과 앞뒤 일정 부분까지만입니다. 나머지는 그대로 파일에 있게 되지요.
-
아이
제 실험 결과 18 메가 정도까지 차면 아웃오브메모리 나오더군요^^ int형의 최대치까지 가능하다면 2기가는 될 수 있을 것 같은데 ㅎㅎ
-
참이삭
RandomAccessFile rf=new RandomAccessFile(path,\r\);
byte [] TT=new byte[(int)rf.length()];
rf.readFully(TT);
System.out.println(TT.length);
String ss=new String(TT);
System.out.println(\과연 outOfmemory는 ?? ^^;\);
HDicCheck.this.errEditArea.setText(ss) -
장미빛볼살
String을 만드는 과정에서 역시나 outofMemory 가 일어나는군요 ㅜ
-
도리도리
선듯이해가 안가네요 ㅜㅜ 방금 Byte배열로 받아 냈을때는 아무탈없었는데 String 에 append 하는 과정에 무언가 모르는 일이일어나는건가요?
-
에녹
다시 의문점이 생기는데요 그렇다면 메모장에서도 받아내는 크기의(30메가)의 텍스트를 JTextArea에서 받아 낼수 없는것인가요?
-
이슬비
아하 모두 감사드립니다. ^^ 복받으세요 ^^
-
슬예
저도 출력을 쪼개는 방법을 선택할 것 같습니다.
FileOutputStream() 에서 append 모드로 해당 화일을 쓸 수 있습니다. ^_^ ( 자세한것은 API 를 ㅎㅎ ) -
로다
heap의 사이즈를 늘릴수도 있으나 좋은 방안은 아닌듯 싶구요. 출력을 쪼갤 수도 있겠구요. 아니면 출력값을 버퍼에 담지 말고, 바로 RandomAccessFile을 이용해 파일에 직접 출력해줄 수도 있을 것 같구요. 아니면 NIO의 버퍼나 채널 클래스를 이용할 수도 있겠지요.
-
온새미로
while 문 안에 sb.append 하실 때 마다 콘솔로 sb의 길이를 출력 하도록 해보시고 돌려 보세요,
API 에는 내부 버퍼가 오버 플로우 날 경우 자동적으로 증가합니다. 라고 자신 있게 써 있는데(최대 용량이 명시되어 있는 곳은 못찾겠군요^^;;;). 한 스트링 버퍼의 길이를 정해 주거나 길이를 알아내는 함수의 경우 int 형인자로 주고 받는데요; 이걸로 짐작해 본다면 int형의 최대값만큼 스트링 버퍼의 길이가 한정되 있다고도 제 나름대로 짐작