apache poi(XSSFWorkbook API) 가 갖고 있는 메모리 이슈로 인해 full gc가 지속적으로 발생할 수 있다

이를 근본적으로 해결하기 위해서는 read 시에 메모리 사용 증대가 발생되지 않도록 개선된 무언가가 필요하다.

xml 처리 방식도 있고, 여러가지가 있지만 개인적으로 좋은 api를 발견  업무에 적용하여 해결하여서 공유하고자 한다.



출처는 https://github.com/monitorjbl/excel-streaming-reader


pom.xml에 아래 라이브러리 추가

(해당 라이브러리는 위의 git 에서 가져올 수 있다)

  <dependency>
    <groupId>com.monitorjbl</groupId>
    <artifactId>xlsx-streamer</artifactId>
    <version>2.1.0</version>
  </dependency>


결국엔 대량 데이터를 읽어오면서 대량의 메모리 이슈가 발생되므로

읽어오는 부분을 아래의 api를 적용하면 깔끔하게 해결되었음

(이해가 안되면.... 사용방법은 위 출처의 영문을 조금만 읽어보면 활용방법 파악이 될수 있다.)

import com.monitorjbl.xlsx.StreamingReader;

InputStream is = new FileInputStream(new File("/path/to/workbook.xlsx")); Workbook workbook = StreamingReader.builder() .rowCacheSize(100) // number of rows to keep in memory (defaults to 10) .bufferSize(4096) // buffer size to use when reading InputStream to file (defaults to 1024) .open(is); // InputStream or File for XLSX file (required)


apache poi(XSSFWorkbook API)가 갖고 있는 메모리 이슈로 인해 full gc가 발생하는 현상 해결을 위해

엑셀파일 read시에 메모리 사용증대가 발생되지 않는 개선된 api가 필요


구글링 결과 어떤 분이 감사한 모듈을 개발해 놓으셨다.

해결책은 StreamingReader 를 사용하는 것


해결을 위해서는 아래 내용을 참고하면 된다.

해당 블로그에 잘 설명되어 있음

https://github.com/monitorjbl/excel-streaming-reader


회사에서 해당 모듈을 사용하여 고질적 문제를 해결함.


개요는 아래와 같음

  <dependency>
    <groupId>com.monitorjbl</groupId>
    <artifactId>xlsx-streamer</artifactId>
    <version>2.0.0</version>
  </dependency>

Implementation Details

This library will take a provided InputStream and output it to the file system. The stream is piped safely through a configurable-sized buffer to prevent large usage of memory. Once the file is created, it is then streamed into memory from the file system.

The reason for needing the stream being outputted in this manner has to do with how ZIP files work. Because the XLSX file format is basically a ZIP file, it's not possible to find all of the entries without reading the entire InputStream.

This is a problem that can't really be gotten around for POI, as it needs a complete list of ZIP entries. The default implementation of reading from an InputStream in POI is to read the entire stream directly into memory. This library works by reading out the stream into a temporary file. As part of the auto-close action, the temporary file is deleted.

If you need more control over how the file is created/disposed of, there is an option to initialize the library with a java.io.File. This file will not be written to or removed:

File f = new File("/path/to/workbook.xlsx");
Workbook workbook = StreamingReader.builder()
        .rowCacheSize(100)    
        .bufferSize(4096)     
        .open(f);

This library will ONLY work with XLSX files. The older XLS format is not capable of being streamed.




어느 날 회사 출근해서 이클립스를 띄웠는데 갑자기 뜨질 않았다.

이클립스 하단의 상태표시줄에 building workspace 0%.. 까지만 뜨고 응답없음.

메모리 수치도 바꿔보고 이것 저것 해보다가 안대서 검색해보니 여러가지 방법이 있었는데..

메뉴의 Window - Preferences - General - Workspace 에서 Build automatically 를 체크해제하라는 답이 가장 괜찮아 보였다. 하지만 이클립스가 아예 뜨지 않는 상황이라서 -_-;;

좀 더 찾아보니 우리의(?) 스택 오버플로우 사이트에서 아래와 같은 답변을 찾음!


그래서 워크스페이스 폴더의 .metadata\.plugins\org.eclipse.core.resources\projects 에 들어가서 프로젝트들 폴더를 다른 곳으로 옮겨놓고 시동하니 잘됨.

그런데 폴더가 없어서 문제가 되는 프로젝트도 있어서, 하나씩 다시 원래 위치로 옮겨놓았더니 아무런 에러없이 잘된다.

이상, 뭔가 아예 시동이 안될 경우 해볼 수 있는 팁이였다 -_-ㅋ


@SuppressWarnings("rawtypes")


이클립스가 권해주는 어노테이션.

컴파일러가 일반적으로 경고하는 내용 중 "이건 하지마"하고 제외시킬 때 쓰는 것.
옵션을 확인해보니 다음과 같았다. (blog의 내용이다) 
  1. all : 모든 경고  
  2. cast : 캐스트 연산자 관련 경고
  3. dep-ann : 사용하지 말아야 할 주석 관련 경고
  4. deprecation : 사용하지 말아야 할 메서드 관련 경고
  5. fallthrough : switch문에서 break 누락 관련 경고
  6. finally : 반환하지 않는 finally 블럭 관련 경고
  7. null : null 분석 관련 경고
  8. rawtypes : 제너릭을 사용하는 클래스 매개 변수가 불특정일 때의 경고
  9. unchecked : 검증되지 않은 연산자 관련 경고
  10. unused : 사용하지 않는 코드 관련 경고


출처 : http://agagomty.blogspot.kr/2012/12/suppresswarningsrawtypes.html


+ Recent posts