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
이나 별도 캐시 구조 활용