Why do I get "Too many open files" errors?
I find myself having to explicitly call System.gc() in my Groovy scripts to prevent errors like the one below. Why doesn't the garbage collector do this for me? Is there something I can do to cause it to garbage collect to prevent these errors (maybe JAVA_OPTS)?
Caught: java.util.concurrent.ExecutionException: org.codehaus.groovy.runtime.InvokerInvocationException: java.io.IOException: Cannot run program "ls": java.io.IOException: error=24, Too many open files
at groovyx.gpars.GParsPool.runForkJoin(GParsPool.groovy:305)
at UsageAnalyzer$_run_closure2_closure6.doCall(UsageAnalyzer.groovy:36)
at groovyx.gpars.GParsPool$_withExistingPool_closure1.doCall(GParsPool.groovy:170)
at groovyx.gpars.GParsPool$_withExistingPool_closure1.doCall(GParsPool.groovy)
at groovyx.gpars.GParsPool.withExistingPool(GParsPool.groovy:169)
at groovyx.gpars.GParsPool.wit开发者_如何学JAVAhPool(GParsPool.groovy:141)
at groovyx.gpars.GParsPool.withPool(GParsPool.groovy:117)
at groovyx.gpars.GParsPool.withPool(GParsPool.groovy:96)
at UsageAnalyzer$_run_closure2.doCall(<removed>)
at UsageAnalyzer.run(<removed>)
This stack trace is from a parallel program but it happens in sequential programs as well.
As you're using groovy, you can use the convenient methods such as File.withReader()
, File.withWriter()
, File.withInputStream()
, InputStream.withStream()
to ensure resources get closed cleanly. This is less cumbersome than using Java's try .. finally
idiom, as there's not need to explicitly call close()
, or declare a variable outside the try
block.
e.g. to read from a file.
File f = new File('/mumble/mumble/')
f.withReader{ r ->
// do stuff with reader here
}
Definitely look for any place you open files or streams and make sure you close them. It's often beneficial to wrap them like this:
final InputStream in = ...;
try
{
// Do whatever.
}
finally
{
// Will always close the stream, regardless of exceptions, return statements, etc.
in.close();
}
精彩评论