When creating a DatagramSocket if the bind to a UDP port fails
then the constructor throws an exception but the native socket
has still been allocated. The native socket is associated with
the datagram implementation and this will be released once the
implementation has been GC'ed and the finalizer runs.
For the period of time until the finalizer run the native socket
is allocated and this can potentially cause a problem on operating
systems with a limited number of socket fds.
In some applications it is necessary to retry the DatagramSocket
until it fails but this has the negative side effect that all
the fds get used up.
The following is a test case to demonstrate the issue on
Solaris. In the suggested fix section of this bug I include a
fix to close the native socket when the bind fails.
import java.net.DatagramSocket;
import java.net.BindException;
import java.net.SocketException;
public class SocketTest {
public static void main(String args[]) {
int i = 0;
while (true) {
try {
DatagramSocket s = new DatagramSocket(7070);
} catch (BindException e) {
// ignore already in use
} catch (SocketException e) {
System.out.println("SocketException after " + i +
" iterations");
e.printStackTrace();
break;
}
i++;
if ( (i % 100) == 0) {
System.out.println("Up to iteration: " + i);
}
}
}
}