相关疑难解决方法(0)

IOException:打开的文件太多

我正在尝试在Linux上的Jetty 7.0.1中运行的Java webapp中调试文件描述符泄漏.

由于打开的文件过多而导致请求开始失败,应用程序已经愉快地运行了一个月左右,并且必须重新启动Jetty.

java.io.IOException: Cannot run program [external program]: java.io.IOException: error=24, Too many open files
    at java.lang.ProcessBuilder.start(ProcessBuilder.java:459)
    at java.lang.Runtime.exec(Runtime.java:593)
    at org.apache.commons.exec.launcher.Java13CommandLauncher.exec(Java13CommandLauncher.java:58)
    at org.apache.commons.exec.DefaultExecutor.launch(DefaultExecutor.java:246)
Run Code Online (Sandbox Code Playgroud)

起初我认为问题在于启动外部程序的代码,但它使用的是commons-exec,我没有看到它有什么问题:

CommandLine command = new CommandLine("/path/to/command")
    .addArgument("...");
ByteArrayOutputStream errorBuffer = new ByteArrayOutputStream();
Executor executor = new DefaultExecutor();
executor.setWatchdog(new ExecuteWatchdog(PROCESS_TIMEOUT));
executor.setStreamHandler(new PumpStreamHandler(null, errorBuffer));
try {
    executor.execute(command);
} catch (ExecuteException executeException) {
    if (executeException.getExitValue() == EXIT_CODE_TIMEOUT) {
        throw new MyCommandException("timeout");
    } else {
        throw new MyCommandException(errorBuffer.toString("UTF-8"));
    }
}
Run Code Online (Sandbox Code Playgroud)

在服务器上列出打开的文件我可以看到大量的FIFO:

# lsof -u jetty
... …
Run Code Online (Sandbox Code Playgroud)

java linux jetty file-descriptor ioexception

26
推荐指数
5
解决办法
9万
查看次数

grails应用程序中的"打开文件太多" - 如何正确关闭打开的文件和流?

我正在开发一个相当复杂的Web应用程序,它调用几个外部执行的进程,一个grails后台进程和几个文件的读/写 - 所有这些都在一个控制器中.一切都很好,直到我在近距离接近许多请求测试它.当我这样做时,我在我的tomcat catalina日志文件中收到以下java错误消息:

WARNING: Exception executing accept
java.net.SocketException: Too many open files
    at java.net.PlainSocketImpl.socketAccept(Native Method)
    at java.net.PlainSocketImpl.accept(PlainSocketImpl.java:408)
    at java.net.ServerSocket.implAccept(ServerSocket.java:462)
    at java.net.ServerSocket.accept(ServerSocket.java:430)
    at org.apache.jk.common.ChannelSocket.accept(ChannelSocket.java:312)
    at org.apache.jk.common.ChannelSocket.acceptConnections(ChannelSocket.java:666)
    at org.apache.jk.common.ChannelSocket$SocketAcceptor.runIt(ChannelSocket.java:877)
    at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:690)
    at java.lang.Thread.run(Thread.java:662)
Run Code Online (Sandbox Code Playgroud)

起初,经过一些快乐的googeling和阅读之后,我怀疑它可能是一个"系统问题",即我必须为执行tomcat的用户提高打开文件的限制 - 但事实并非如此.

然后我开始阅读关于Java的很多建议,而不是Grails和Groovy,因为如果你用Grails来解决这个问题,你就找不到这么多了.我现在怀疑我的问题是由"太多的开放流"(或类似的东西)引起的,而不是实际打开的文件太多(因为打开文件的数量确实不是很大).

我在一个闭包中有以下四种类型的大量操作:

1)打开文件并写入文件:

def someFile = new File("/some/file.txt")
someFile << "Some content\n"
Run Code Online (Sandbox Code Playgroud)

2)执行命令:

def cmd = "bash some-cmd".execute()
cmd.waitFor()
Run Code Online (Sandbox Code Playgroud)

3)从文件中读取内容:

def fileContent = new File("/some/file.txt").text
Run Code Online (Sandbox Code Playgroud)

4)从Web上的文件中读取内容:

def URL url = new URL("http://www.some.link");
def URLConnection uc = url.openConnection()
def BufferedReader br = new BufferedReader(new InputStreamReader(uc.getInputStream()))
... …
Run Code Online (Sandbox Code Playgroud)

java grails groovy tomcat file

5
推荐指数
1
解决办法
3090
查看次数

标签 统计

java ×2

file ×1

file-descriptor ×1

grails ×1

groovy ×1

ioexception ×1

jetty ×1

linux ×1

tomcat ×1