これに具体的に対処する方法がわかりません(Javaの新機能)。基本的に、メモリを超えた多くのデータを生成するプログラムがあります (たとえば、10 ギガのデータと 4 ギガの RAM があります)。データを取得してディスクに書き込むスレッドをフォークすることにしましたが、ディスクへの書き込みがそれを生成するプロセスに追いつかないことはわかっていますが、アプリケーションがディスクへの書き込み速度にバインドできることを望んでいました。しかし、しばらくするとヒープ不足のエラーが発生します。
関連すると思われる部分は次のとおりです。書き込まれるすべてのデータは、この変数に入れられます。
private static Queue<short[]> result = new LinkedList <short[]> ();
ファイルに保存する部分は次のとおりです。
static class SaveToFile extends Thread {
public void run() {
FileWriter bw = null;
try {
bw = new FileWriter("output.csv");
Thread.sleep(500); //delay the start so the queue can have some data
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("size of results during execution is " + result.size());
while(!result.isEmpty()) {
short[] current = result.poll();
try {
bw.write(Arrays.toString(current) + "," + "\n");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
try {
bw.flush();
bw.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("file writing is done");
}
}
何が間違っているのかわかりません。結果のキューを特定のサイズでブロックして、プロセスが書き込みを停止する必要がありますか? または、ファイルへの書き込みに何か問題がありますか? バッファリングされていないバージョンを表示していますが、bufferedWriter を試してみましたが、同じ結果が得られましたか? プログラムの実行中にファイル サイズが 0 になっていることを確認しましたが、一度だけクラッシュしたように見えます。
私の考えは、SaveToFile スレッドがキューをクリアすると、他のプロセスがキューに書き込みを続けるためのスペースが増えるということでした (これらは、私が実行している唯一のスレッド、メイン プログラムと SaveToFile です)。