大きなテキストコーパスをJavaでメモリに読み込もうとしています。ある時点で壁にぶつかり、ゴミがたまらなく収まります。誰かがJavaのGCを破って大量のデータセットを送信する経験があるかどうか知りたいのですが。
8 GBの英語テキストファイルをUTF-8で、1行に1文ずつ読んでいます。私がしたいsplit()
空白の各ラインと、その結果文字列を格納しArrayList<String[]>
、さらなる処理のために。問題を示す簡単なプログラムを次に示します。
/** Load whitespace-delimited tokens from stdin into memory. */
public class LoadTokens {
private static final int INITIAL_SENTENCES = 66000000;
public static void main(String[] args) throws IOException {
List<String[]> sentences = new ArrayList<String[]>(INITIAL_SENTENCES);
BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
long numTokens = 0;
String line;
while ((line = stdin.readLine()) != null) {
String[] sentence = line.split("\\s+");
if (sentence.length > 0) {
sentences.add(sentence);
numTokens += sentence.length;
}
}
System.out.println("Read " + sentences.size() + " sentences, " + numTokens + " tokens.");
}
}
かなりカットアンドドライですね。私が私のサイズを事前に設定していることに気付くでしょうArrayList
。私は6600万弱の文と13億のトークンを持っています。今、あなたはあなたのサッと取り出した場合にJavaオブジェクトのサイズを参照し、あなたの鉛筆を、あなたは約要求すべきであることを見つけることができます:
String[]
参照@ 8バイトEA = 0.5 GBString[]
オブジェクト@ 32バイトEA = 2 GBchar[]
オブジェクト@ 32バイトEA = 2 GBString
参照@ 8バイトEA = 10 GBString
s @ 44バイトea = 53 GBchar
s @ 2バイトea = 15 GB83 GB。(圧縮OOPは32 GBを超えるヒープでは役に立たないため、64ビットのオブジェクトサイズを使用する必要があることに気付くでしょう。)128 GBのRAMを備えたRedHat 6マシンがあるので幸いです。pv giant-file.txt | java -Xmx96G -Xms96G LoadTokens
安全のために、Java SE 1.6.0_29キットからJava HotSpot(TM)64ビットサーバーVM(ビルド20.4-b02、混合モード)を起動し、を見ながらキックバックしtop
ます。
入力の半分未満のどこか、RSSが約50〜60 GBの場合、パラレルガベージコレクターは最大1300%のCPU(16 procボックス)を起動し、読み取りの進行が停止します。次に、それは数GB増加し、その後、進行はさらに長く停止します。容量は96 GBですが、まだ完了していません。私はそれを1時間半放置しました、そしてそれはちょうどGCをしている〜90%システム時間を燃やしています。それは極端に思えます。
気が狂っていないことを確認するために、私は同等のPython(2行すべて)を作成し、約12分で70 GBのRSSで完了しました。
だから:私は何かばかげていますか?(一般的に非効率的な方法でデータを保存する方法は別として、私は本当に手助けすることはできません。データ構造が太っていても、Javaが収まらない限り、Javaは窒息しないでください。)魔法のGCアドバイスはありますか?本当に大きなヒープのために?私は試しましたが-XX:+UseParNewGC
、それはさらに悪いようです。
-XX:+UseConcMarkSweepGC
:78 GBで終了し、約12分です。(Pythonとほぼ同じです!)皆の助けに感謝します。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加