在Mac OS上调查这个JDK错误时,我遇到了系统调用跟踪输出,我不明白:
Tomcat startup fails due to ‘java.net.SocketException Invalid argument’ on Mac OS X
简短版本:在Mac OS上,JDK使用select()而不是poll().因此,如果分配了超过1024个文件描述符,我们推断出NET_Timeout中的select()调用失败,导致带有“无效参数”消息的SocketException.但是,当我跟踪系统调用时,我没有看到select()系统调用或任何失败的调用并设置EINVAL的证据,因此我将其视为潜在原因.
我也没有看到我现在创建的缩减测试用例的调用我理解了这个问题:
import java.io.*; import java.net.*; public class SelectTest { public static void main(String[] args) throws Exception { for(int i = 0; i < 1024; i++) { new FileInputStream("/dev/null"); } ServerSocket socket = new ServerSocket(8080); socket.accept(); } }
在Mac OS w / JDK 1.7u5及更高版本中导致此例外:
Exception in thread "main" java.net.SocketException: Invalid argument at java.net.PlainSocketImpl.socketAccept(Native Method) at java.net.AbstractPlainSocketImpl.accept(AbstractPlainSocketImpl.java:398) at java.net.ServerSocket.implAccept(ServerSocket.java:522) at java.net.ServerSocket.accept(ServerSocket.java:490) at SelectTest.main(SelectTest.java:12)
当我使用sudo dtruss -a java SelectTest运行测试时,为什么我看不到任何有关select()(或任何其他失败)调用的证据?
PID/THRD RELATIVE ELAPSD cpu SYSCALL(args) = return 45563/0x63a513: 85544 6 4 bind(0x412,0x10DFC7738,0x1C) = 0 0 45563/0x63a513: 85605 6 3 listen(0x412,0x32,0x32) = 0 0 45563/0x63a513: 85619 2 0 lseek(0x4,0x37377AD,0x0) = 57898925 0 45563/0x63a513: 85622 4 2 read(0x4,"PK\003\004\n\0",0x1E) = 30 0 45563/0x63a513: 85622 1 0 lseek(0x4,0x37377E0,0x0) = 57898976 0 45563/0x63a513: 85627 5 4 read(0x4,"\312\376\272\276\0",0x3447) = 13383 0 45563/0x63a513: 86150 37 33 write(0x2,"Exception in thread \"main\" ble\001\0",0x1B) = 27 0
解决方法
我希望ServerSocket.accept能够正好调用你所看到的内容.
对应于Java接受的Berkeley套接字调用是listen()和accept()
不幸的是我无法在linux上重现异常.如果我在新的ServerSocket(8080)之前使用所有fd,我得到:
Exception in thread "main" java.lang.UnsatisfiedLinkError: /usr/lib/jvm/java-7-oracle/jre/lib/amd64/libnet.so: /usr/lib/jvm/java-7-oracle/jre/lib/amd64/libnet.so: cannot open shared object file: Too many open files at java.lang.ClassLoader$NativeLibrary.load(Native Method) at java.lang.ClassLoader.loadLibrary1(ClassLoader.java:1939) at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1864) at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1846) at java.lang.Runtime.loadLibrary0(Runtime.java:845) at java.lang.System.loadLibrary(System.java:1084) at sun.security.action.LoadLibraryAction.run(LoadLibraryAction.java:67) at sun.security.action.LoadLibraryAction.run(LoadLibraryAction.java:47) at java.security.AccessController.doPrivileged(Native Method) at java.net.AbstractPlainSocketImpl.<clinit>(AbstractPlainSocketImpl.java:80) at java.net.ServerSocket.setImpl(ServerSocket.java:289) at java.net.ServerSocket.<init>(ServerSocket.java:230) at java.net.ServerSocket.<init>(ServerSocket.java:128) at SelectTest.main(SelectTest.java:15)