多くのファイルを読み書きする必要がある遺伝的アルゴリズムを書いています。gradif
GA の適合性テストは、ファイルを入力として受け取り、出力としてファイルを生成するというプログラムを呼び出しています。
遺伝的アルゴリズムの人口サイズや総世代数を大きくしすぎた場合を除いて、すべてが機能しています。その後、何世代にもわたって、次のようになりましjava.io.FileNotFoundException: testfiles/GradifOut29 (Too many open files)
た。(多くの異なるファイルに対して繰り返し取得します。インデックス29
は、前回実行したときに最初に表示されたものにすぎません)。第 1 世代または第 2 世代の後にエラーが発生しないのは奇妙ですが、かなりの量の世代が経過した後です。これは、各世代が閉じないより多くのファイルを開くことを示唆しています。しかし、私が知る限り、すべてのファイルを閉じています。
コードの設定方法は、main()
関数がPopulation
クラス内にあり、Population
クラスに の配列が含まれていることですIndividuals
。これが私のコードです:
入力ファイルの初期作成 (複数の世代にわたって同じファイルを再利用できるように、それらはランダム アクセスです)
files = new RandomAccessFile[popSize];
for(int i=0; i<popSize; i++){
files[i] = new RandomAccessFile("testfiles/GradifIn"+i, "rw");
}
プログラム全体の最後に:
for(int i=0; i<individuals.length; i++){
files[i].close();
}
Individual
のフィットネス テストの内部:
FileInputStream fin = new FileInputStream("testfiles/GradifIn"+index);
FileOutputStream fout = new FileOutputStream("testfiles/GradifOut"+index);
Process process = Runtime.getRuntime().exec ("./gradif");
OutputStream stdin = process.getOutputStream();
InputStream stdout = process.getInputStream();
じゃあ後で....
try{
fin.close();
fout.close();
stdin.close();
stdout.close();
process.getErrorStream().close();
}catch (IOException ioe){
ioe.printStackTrace();
}
その後、ファイルに「END」を追加して、解析を容易にします。
FileWriter writer = new FileWriter("testfiles/GradifOut"+index, true);
writer.write("END");
try{
writer.close();
}catch(IOException ioe){
ioe.printStackTrace();
}
stdin と stdout のリダイレクトは、この回答gradif
からのものです。構文を使用して、ファイルを閉じる際に問題があるかどうかを確認してみました (ありませんでした) 。この回答からそれを得ました。try{close()}catch{}
Individual
s のフィットネス テストが同時に実行されることにも注意してください。
exec()
更新: 私は実際にそれを呼び出しに絞り込むことができました. 最近の実行では、最初に世代 733 (人口サイズ 100) で問題に遭遇しました。なぜ前の世代は大丈夫なのですか?リークがない場合、アルゴリズムは以前の世代を通過できるはずですが、後の世代では失敗する理由がわかりません。また、漏れがあるとすれば、どこから漏れているのでしょうか?
更新 2: ここで何が起こっているのかを把握しようとして、JVM が任意の時点で開いているファイルの数を (できればリアルタイムで) 確認できるようにしたいと考えています。それを行う簡単な方法はありますか?