我正在编写一个需要读取/写入大量文件的遗传算法。GA的适用性测试是调用一个名为gradif
的程序,该程序将文件作为输入并生成文件作为输出。
一切都在工作,除非我使遗传算法的种群规模和/或总代数太大。然后,经过这么多代人,我开始得到这个:java.io.FileNotFoundException:testfiles/GradifOut29(太多打开的文件)。
(我为许多不同的文件反复得到它,索引 29
只是我上次运行它时首先出现的那个)。这很奇怪,因为我不是在第一代或第二代之后得到错误,而是在相当多的世代之后,这表明每一代都会打开更多它没有关闭的文件。但据我所知,我正在关闭所有文件。
代码的设置方式是< code>main()函数位于< code>Population类中,而< code>Population类包含一个< code >个体数组。这是我的代码:
输入文件的初始创建(它们是随机访问的,因此我可以跨多代重用同一个文件)
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();
}
在个人
的适应度测试中:
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
的stdin和stdout的重定向来自这个答案。我尝试使用try{封闭()}抓住{}
语法来查看关闭任何文件是否有问题(没有),我从这个答案中得到了这个答案。
还应该注意的是,个人
的体能测试同时进行。
更新:我实际上已经能够将其缩小到exec()
调用。在我最近的一次跑步中,我第一次遇到麻烦是在733代(人口规模为100人)。为什么前几代人还好?我不明白为什么,如果没有泄漏,算法应该能够通过前几代,但在后几代失败。如果有泄漏,那么它从哪里来?
更新2:在试图弄清楚这里发生了什么时,我希望能够看到(最好是实时)JVM在任何给定点打开了多少文件。有没有简单的方法可以做到这一点?
您似乎在linux(或某些类似unix的操作系统)上运行。您可以使用“lsof”命令之类的东西来确定您的应用程序在收到错误时打开了哪些文件。
尝试关闭错误流:
process.getErrorStream().close();
编辑:事实上你也应该读一下,因为错误流的缓冲区满了会阻塞子进程。
在这里看一个StreamGobbler实现:需要样本Java代码来运行shellscript
编辑2:是否有人口规模(足够小),无论世代计算,您都不会遇到问题?如果是这种情况,您可能不再泄漏打开的文件/流。
在这种情况下,您有两种解决方案:
也许把你所有的行为都放在循环中是个好主意:
while(selection_ of_file.hasNext()){
File are new randomFile
open inputFile
open outPufile
read from inputFile
write to outputFile
close inputFile
close outputFile
}
问题内容: 我已经与Tornado进行了很多合作,但这是我第一次遇到这种错误。我一直在研究一个非常基本的URL缩短器。URL由另一种应用程序放入数据库中,该应用程序仅从MongoDB存储中读取URL并重定向客户端。编写基本代码后,我针对它设置了一个简单的“ Siege”测试,在运行siege(针对4个应用程序线程运行)约30秒钟之后,我开始获得500个响应。查看错误日志,我看到了; 重要(我想);
我想知道太多文件打开错误的确切问题。我通过谷歌寻找解决方案,但我不知道为什么会出现这个问题以及如何解决这个问题。 堆栈错误:严重:套接字接受失败。网SocketException:java上打开的文件太多。网普通袜子。java上的socketAccept(本机方法)。网抽象素socketimpl。在java上接受(AbstractPlainSocketImpl.java:398)。网服务器插座。j
我正试图运行Jest测试,但得到以下错误: 令我感兴趣的是,错误中列出的路径指向node_modules目录中的一个文件,由于TestPathIgnorePatterns中的node_modules条目,我预计该文件不会被读取。 我运行的是节点4.2.1,我的React-Native安装才一周,我今天安装了Jest(所以我想我对所有东西都是最新的)。我在Mac电脑上。 我运行了:,关闭了所有终端窗
我正在使用线程每5秒钟通过终端连接。但是我在1天后得到了“java.io.IOException:无法运行程序”/bin/bash“: error=24,打开的文件太多”。 线程程序: 工艺方法: 例外: 我用的是CENT OS。 请朋友们帮助我,如何解决这个问题。
我有一个在tomcat上运行的应用程序,有时会出现以下错误: .... 我检查了打开文件的限制,它是1024个,但是当我检查了lsof应用程序的打开文件数量时,它接近200个,如果它没有达到限制,为什么会发生这种情况?我应该增加限额吗?是否有其他原因导致此错误?让服务重新正常运行的唯一方法是重新启动tomcat,还有其他恢复正常的方法吗? 提前谢谢。 编辑:这里是处理doPost方法的servle
问题内容: 我的Java程序失败了 这是来自的关键行。他们将用户的最大文件数设置为500k: 我跑去统计打开的文件数- 包括全局和jvm进程。我检查了中的柜台。一切似乎还可以。我的进程仅打开了4301个文件,限制为500k: 这是Ubuntu 11.04服务器。我什至已经重新启动,所以我很肯定正在使用这些参数。 我不知道它是否相关,但是该过程由upstart脚本启动,该脚本使用setuidgid启