2016-08-24 10 views
0

現在、我々はエクセルにダウンロードしてダウンロードするためにDBに保存されたレコードをエクスポートするためにXSSFを使用しています。我々の要求に応じて、ユーザーは300万レコードをダウンロードできるようにする必要があります。OutOfMemoryまたはXSSFを使用したGCオーバーヘッド

XSSFでは、OutOfMemoryError:GCオーバーヘッドの上限を超えています。

私はいくつかの研究を行い、XSSFが記憶に飢えていることを知りました。私の要求を達成するためのよりよい方法を提案する人もいます。データをExcel形式でダウンロードする必要があり、ディスクに明示的に書き込む必要はありません。

+3

[ApacheのPOIと超過GCオーバーヘッドの制限](http://stackoverflow.com/questions/33368612/gc-overhead-limit-exceeded-with-apache-poi)の可能性の重複 –

答えて

0

POI APIを使用できます。 私たちは、POI APIを使用してプログラムで大きなエクセルファイルを使用してストリーミングを実装しました。メモリに保存されている行のサイズを低く保つことが重要です。残りは基本的にディスク上で行われます。

また、SXSSFWorkbook.setCompressTempFilesを設定して、一時的なXMLファイルがディスク上で大きくなるのを防ぐことができます。

flushRows()を使用すると、手動で行をディスクにフラッシュできます。

ただし、これは遅いです。しかし、メモリが制約の場合は唯一の選択肢です。

いくつかの方法では、暗黙的に行にアクセスすることに注意してください。これらの行が既にディスクにスワップされている場合は、エラーが発生します。また、APIは大規模なエクセルファイルを書き込むためだけに使用されます。

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 
     } 
    } 
関連する問題