2017-10-17 12 views
0

私はプレーンテキストのファイルを読み込み、1行ずつ読み込み、各行をセンテンスに分割し、各センテンスを単語に分割し、1文および1文書ごとにリストに格納します。このGCオーバーヘッドの上限を超えるのはなぜですか?

入力ファイルを5万行が含まれているので、私はIntelliJの中に私のヒープサイズは以下の通りです5005000.するのArrayListのサイズを設定:

# custom IntelliJ IDEA VM options 

-Xms128m 
-Xmx8192m 
-XX:ReservedCodeCacheSize=240m 
-XX:+UseConcMarkSweepGC 
-XX:SoftRefLRUPolicyMSPerMB=50 
-ea 
-Dsun.io.useCanonCaches=false 
-Djava.net.preferIPv4Stack=true 
-XX:+HeapDumpOnOutOfMemoryError 
-XX:-OmitStackTraceInFastThrow 

私のラップトップは15G RAMを持っています。 4500000行(printステートメントで示されている)を読み取った後、非常に遅くなります。数分後、私が受け取っ:

Exception in thread "main" java.lang.OutOfMemoryError: GC overhead limit exceeded 

(一つの文書としてパース)各行が短いので、私の15Gメモリがそれを保持するのに十分以上でなければなりません。テキストファイルのサイズはわずか800MBです。 Windows 10でパフォーマンスモニタを見ているうちに、約55%のメモリしか使用されていないことが示されています。

英語ではないので、以下のコードでは「sentence.toCharArray()」を使用します。基本的には、各文字を実装の単語として扱います。

500万回線しかありませんが、なぜそれは死んでいますか?

 List<List<List<String>>> allWords = new ArrayList<>(5005000); 
     System.out.println("Load text from file: "); 
     try { 
      BufferedReader br = Utils.fileReader(filePath); 

      String line; 
      int lineNo = 0; 
      while ((line = br.readLine()) != null) { 
       List<List<String>> wordsPerDoc = new ArrayList<>(); 
       for (String sentence : segment(line)) { 
        List<String> wordsPerSentence = new ArrayList<>(); 
        for (Character c : sentence.toCharArray()) { 
         wordsPerClause.add(Character.toString(c)); 
        } 
        wordsPerDoc.add(wordsPerSentence); 
       } 
       allWords.add(wordsPerDoc); 
       lineNo++; 
       if(lineNo % 500000 ==0) { 
        System.out.println(lineNo); 
       } 
      } 
      System.out.println("Loaded text from file. "); 

      br.close(); 

     } catch (IOException e) { 
      e.printStackTrace(); 
     } finally { 
      if (br != null) { 
       try { 
        br.close(); 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 
      } 
     } 

public List<String> segment(final String line) { 
     List<String> sentences = new ArrayList<>(); 
     StringTokenizer tokenizer = new StringTokenizer(line, OtherConstants.BASIC_TOKENIZATION_DELIMITER, true); 
     while (tokenizer.hasMoreTokens()) { 
      String word = tokenizer.nextToken(); 
       sentences.add(word); 
     } 
     return sentences; 
    } 

答えて

0

あなたは IntelliJのためのメモリプロファイルを変更しています。

アプリの代わりに変更するには:右上の実行メニューに移動します。あなたのメインクラスを見つける。 "Edit Configurations"をクリックしてください。アプリの4 GBヒープの場合は「VMオプション」を-Xmx4gに設定します。

https://www.jetbrains.com/help/idea/run-debug-configuration-application.html(docs)

関連する問題