OutOfMemory или GC с использованием XSSF
В настоящее время мы используем XSSF для экспорта записей, хранящихся в БД, чтобы преуспеть и загрузить их. Согласно нашему требованию, мы должны разрешить пользователю загружать 3 миллиона записей.
С XSSF мы сталкиваемся с OutOfMemoryError: Превышен лимит накладных расходов GC.
Я провел некоторое исследование и узнал, что XSSF жаждет памяти. Может ли кто-нибудь предложить мне лучший способ выполнить мое требование? Обратите внимание, что мне нужно загрузить данные в формате Excel и не хочу явно записывать их на любой диск.
1 ответ
Вы можете использовать POI API. Мы успешно реализовали потоковую передачу с большими файлами Excel в наших программах с использованием POI API. Важно, чтобы размер строки в памяти оставался низким, а остальное в основном делается на диске.
Вы также можете установить: SXSSFWorkbook.setCompressTempFiles, чтобы предотвратить увеличение размера временных файлов XML на диске.
С flushRows() вы можете вручную сбросить строки на диск.
Тем не менее, это медленнее. Но если память является ограничением, единственный вариант.
Имейте в виду, что некоторые методы обращаются к строкам неявно. Если эти строки уже были перенесены на диск, вы также столкнетесь с ошибками, и я считаю, что API предназначен только для записи больших файлов Excel.
public static void main(String[] args) throws Throwable {
SXSSFWorkbook wb = new SXSSFWorkbook();
wb.setCompressTempFiles(true);
SXSSFSheet sh = (SXSSFSheet) wb.getSheetAt(0);
sh.setRandomAccessWindowSize(100);// keep 100 rows in memory, exceeding rows will be flushed to disk, this is also the default
for(int i= 1; i < 100000; i++){
Row row = sh.createRow(i); // do something with the row
}
}