我正在编写一个需要读取/写入大量文件的遗传算法。GA 的适应度测试调用了一个名为 的程序gradif
,该程序将一个文件作为输入并生成一个文件作为输出。
一切正常,除非我使种群大小和/或遗传算法的总代数太大。然后,经过这么多代人,我开始得到这个:java.io.FileNotFoundException: testfiles/GradifOut29 (Too many open files)
。(我为许多不同的文件反复获取它,索引29
只是我上次运行它时第一次出现的那个)。这很奇怪,因为在第一代或第二代之后我没有收到错误,而是在经过大量代之后,这表明每一代都会打开更多它不会关闭的文件。但据我所知,我正在关闭所有文件。
代码的设置方式是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();
}
我对标准输入和标准输出的重定向gradif
来自这个答案。我尝试使用try{close()}catch{}
语法来查看关闭任何文件是否有问题(没有),我从这个答案中得到了。
还应该注意的是,Individual
s 的适应度测试同时运行。
更新:我实际上已经能够将其范围缩小到exec()
通话。在我最近的一次运行中,我第一次遇到麻烦的是第 733 代(人口规模为 100)。为什么前几代还好?我不明白为什么,如果没有泄漏,算法应该能够通过前几代但在后几代失败。如果有泄漏,那么它来自哪里?
UPDATE2:在试图弄清楚这里发生了什么时,我希望能够(最好是实时地)查看 JVM 在任何给定点打开了多少文件。有没有简单的方法可以做到这一点?