我在寫一個需要讀/寫大量文件的遺傳算法。 GA的健身測試正在調用名爲gradif
的程序,該程序將文件作爲輸入並生成文件作爲輸出。java ioexception error = 24太多文件打開
除了當我將遺傳算法的種羣大小和/或總代數變得太大時,所有東西都在工作。然後,經過這麼多代,我開始得到這個: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();
}
然後,我追加一個'結束'的文件,使它們更容易解析。
FileWriter writer = new FileWriter("testfiles/GradifOut"+index, true);
writer.write("END");
try{
writer.close();
}catch(IOException ioe){
ioe.printStackTrace();
}
我對gradif
stdin和stdout重定向來自this answer。我嘗試使用try{close()}catch{}
語法來查看是否有關閉任何文件(沒有)的問題,並且我從this answer得到了該文件。
還應該注意的是Individual
s的健身測試同時運行。
更新:我實際上已經能夠縮小到exec()
的電話。在我最近的一次運行中,我第一次遇到了第733代的麻煩(人口規模爲100)。前幾代爲什麼罰款?我不明白爲什麼,如果沒有泄漏,算法應該能夠通過前幾代,但後代失敗。如果有泄漏,那麼它從哪裏來?
UPDATE2:爲了弄清楚這裏發生了什麼,我希望能夠看到(最好是實時的)JVM在任何給定點打開了多少個文件。有沒有簡單的方法來做到這一點?
watch'lsof -p pid' – Thierry
@Thierry我盡我所能,只是在終端上反覆做這件事。但是有沒有什麼辦法可以設置一些能夠實時顯示lsof文件數量的東西,而不必繼續混合'up,enter'鍵? – MattS
是的,這是手錶命令:「watch。定期執行程序,顯示全屏輸出。」。默認間隔爲2秒,但您可以更改它。 – Thierry