1

モジュールの1つで巨大なファイルを解析し、このファイルをチャンクごとにデータベースに保存するアプリケーションを作成しました。

まず、次のコードが機能します。私の主な問題は、メモリ使用量を減らし、パフォーマンスを全体的に向上させることです。

次のコード スニペットは全体像のごく一部ですが、いくつかの YourKit プロファイリングを行った後に最も問題となるのは、/*Here*/ でマークされた行が大量のメモリを割り当てていることです。

....
Scanner fileScanner = new Scanner(file,"UTF-8");
String scannedFarm;
try{

    Pattern p = Pattern.compile("(?:^.++$(?:\\r?+\\n)?+){2,100000}+",Pattern.MULTILINE);
    String [] tableName = null;

/*HERE*/while((scannedFarm = fileScanner.findWithinHorizon(p, 0)) != null){
         boolean continuePrevStream = false;
         Scanner scanner = new Scanner(scannedFarm);

         String[] tmpTableName  = scanner.nextLine().split(getSeparator());
         if (tmpTableName.length==2){
             tableName = tmpTableName;
         }else{
             if (tableName==null){
                 continue;
             }
             continuePrevStream = true;
         }
         scanner.close();

/*HERE*/ InputStream is = new ByteArrayInputStream(scannedFarm.getBytes("UTF-8"));
....

String が大きいため、大量のメモリを割り当てることは許容されます (私はそれがあまりにも大きなチャンクである必要があります)。私の主な問題は、getBytes の結果として同じ割り当てが 2 回発生することです。

  1. 私の質問は、メモリを 2 回割り当てずに、 findWithinHorizo​​n Result を直接InputStreamに転送する方法ですか?

  2. 同じ機能を実現するためのより効率的な方法はありますか?

4

1 に答える 1

0

まったく同じアプローチではありませんが、代わりにfindWithinHorizon、各行を読み取り、行コンテキスト内でパターンを検索してみてください。API が示すようにファイル全体をバッファリングしていないため、これによりメモリの負荷が確実に軽減されます。

水平線が 0 の場合、水平線は無視され、このメソッドは入力を検索し続け、指定されたパターンを無制限に探します。この場合、 pattern を検索するすべての入力をバッファに入れることができます

何かのようなもの:

while(String line = fileScanner.nextLine() != null) { 
   if(grep for pattern in line) { 

   }
}
于 2013-01-21T20:18:39.870 に答える