/ / OutOfMemory lub GC Overhead z XSSF - java, xssf

OutOfMemory lub GC Overhead z XSSF - java, xssf

Obecnie używamy XSSF do eksportowania zapisów przechowywanych w DB do Excela i pobierania go. Zgodnie z naszym wymaganiem, musimy zezwolić użytkownikowi na pobranie 3 milionów rekordów.

W XSSF mamy do czynienia z OutOfMemoryError: przekroczono limit narzutów GC.

Zrobiłem kilka badań i dowiedziałem się, że XSSF jestgłodny pamięci. Czy ktoś może mi zaproponować lepszy sposób na osiągnięcie mojego wymagania. Należy pamiętać, że muszę pobrać dane w formacie Excela i nie chcę pisać bezpośrednio na żadnym dysku.

Odpowiedzi:

0 dla odpowiedzi № 1

Możesz użyć POI API. Udało nam się zaimplementować przesyłanie strumienioweduże pliki Excela w naszych programach za pomocą API POI. Ważne jest, aby zachować rozmiar wiersza, który jest przechowywany w pamięci na niskim poziomie, reszta jest w zasadzie wykonywana na dysku.

Możesz także ustawić: SXSSFWorkbook.setCompressTempFiles, aby zapobiec tymczasowemu powiększaniu się plików XML na dysku.

Z flushRows () możesz ręcznie opróżnić rzędy na dysk.

Jest to jednak wolniejsze. Ale jeśli pamięć jest ograniczeniem, jedyną opcją.

Pamiętaj, że niektóre metody uzyskują dostęp do wierszy w sposób niejawny. Jeśli te wiersze zostały już zamienione na dysk, napotkasz także błędy. Uważam, że API służy tylko do pisania dużych plików programu 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
}
}