[kaffe] Sockets remain unclosed
Ito Kazumitsu
ito.kazumitsu@hitachi-cable.co.jp
Tue Apr 6 04:22:02 2004
In message "[kaffe] Sockets remain unclosed"
on 04/03/17, Ito Kazumitsu <ito.kazumitsu@hitachi-cable.co.jp> writes:
> Summary:
>
> When you use Jetty with Kaffe, the number of idle sockets
> gradually increases until "too many open files" error may occur.
> The value of Jetty's parameter MaxIdleTimeMs is 10000 ms by default,
> so a new socket is created and thrown away in every 10 seconds.
> Setting MaxIdleTimeMs to a reasonable value will slow down the
> the creation of new sockets and you can avoid "too many open files".
>
> That was not a complete solution. Although the creation of new sockets
> can be slowed down, the number of sockets still increases gradually.
>
> I patched java/net/ServerSocket.java to see if this problem can be
> solved. The result is satisfactory.
Unfortunately, this is not the end of the story.
With the patch to java/net/ServerSocket.java, Jetty works almost
fine. But the number of open sockets still increases slowly but
steadily and in a long run, "too many open files" error will happen.
The problem is:
(1) When accept() is done, two file descriptors are generated.
(2) When the socket is closed, one of the two file descriptors is
closed but the other remains unclosed.
The problem may be OS-dependent and my OS is Linux 2.4.18-3.
I have made a simple program which illustrates the problem.
When run on Linux 2.4.18-3 + kaffe CVS version dated 2004-04-05,
"java.io.IOException: Too many open files" occurs. But when
run on Windows 98 + Sun's JDK 1.4.2_04-b05, this program
runs endlessly without causing such an error.
$ kaffe ConnectToMyself 33333
java.io.IOException: Too many open files
at gnu.java.net.PlainSocketImpl.socketAccept (PlainSocketImpl.java)
at gnu.java.net.PlainSocketImpl.accept (PlainSocketImpl.java:83)
at java.net.ServerSocket.implAccept (ServerSocket.java:373)
at java.net.ServerSocket.accept (ServerSocket.java:329)
at ConnectToMyself$Server.run (ConnectToMyself.java:38)
import java.net.*;
import java.io.*;
public class ConnectToMyself {
private static int serverPort;
private static InetAddress targetServer;
private static int targetPort;
public static void main(String argv[]) throws Exception {
serverPort=Integer.parseInt(argv[0]);
targetPort=serverPort;
targetServer=InetAddress.getByName("localhost");
new Server().start();
Thread.sleep(2000);
new Client().start();
}
private static class Client extends Thread {
public void run() {
try {
while (true) {
Socket targetSocket = new Socket(targetServer,targetPort);
targetSocket.close();
}
}
catch (IOException e) {
e.printStackTrace();
}
}
}
private static class Server extends Thread {
public void run() {
try {
ServerSocket server = new ServerSocket(serverPort);
Socket clientSocket = null;
while (true) {
clientSocket = server.accept();
clientSocket.close();
}
}
catch (IOException e) {
e.printStackTrace();
}
}
}
}