Apache POI SXSSFWorkbook 사용 시 OutOfMemoryError(OOM) 발생 원인 및 해결 전략

Apache POI의 SXSSFWorkbook은 대용량 Excel 파일을 메모리 부담 없이 생성할 수 있는 streaming 기반 API입니다. 하지만 적절히 설정하지 않으면 5만 건 이하의 데이터에서도 OOM(OutOfMemoryError)가 발생할 수 있습니다.

1. OOM 발생 원인

  • flush window size 설정 누락: new SXSSFWorkbook()은 내부적으로 new SXSSFWorkbook(-1)과 동일하여 모든 row를 메모리에 유지합니다.
  • CellStyle 및 Font 객체 반복 생성: 스타일이 루프 안에서 반복 생성되면 PermGen/Metaspace를 빠르게 고갈시킬 수 있습니다.
  • 이미지, 병합 셀 등 복잡한 셀 구성 사용: 스타일과 함께 메모리 부담을 높입니다.
  • dispose() 호출 누락: SXSSF는 임시 파일을 생성하므로, 작업 후 workbook.dispose() 호출이 필수입니다.

2. SXSSFWorkbook 생성 시 올바른 사용 예시

private final SXSSFWorkbook workbook = new SXSSFWorkbook(100); // 메모리에 100개 row 유지
  • 100개의 row까지만 메모리에 유지하고, 초과 시 자동으로 임시 파일로 flush됩니다.
  • 엑셀 파일 완성 시 write() 호출 시 전체 row가 포함되므로, 데이터 누락은 없습니다.

3. SXSSF는 랜덤 접근이 불가능

flush된 row는 메모리에서 제거되며, 이후 sheet.getRow(n)으로 접근할 수 없습니다. SXSSF는 쓰기 전용(write-only) API입니다.

4. CellStyle 캐싱 예시

if (styleData == null) {
    styleData = workbook.createCellStyle();
}
cell.setCellStyle(styleData);

5. 작업 완료 후 리소스 정리

workbook.write(outputStream);
workbook.dispose(); // temp 파일 삭제
workbook.close();

✅ 결론

  • flush window size는 반드시 지정 (예: new SXSSFWorkbook(100))
  • 스타일 캐싱으로 중복 생성 방지
  • 임시 리소스 정리를 위해 dispose() 호출 필수
  • SXSSF는 읽기 불가 → 필요한 경우 XSSFWorkbook이나 별도 캐시 구조 활용

관련 글

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다