Badając ten błąd JDK w systemie Mac OS, pobiegłem do wyjścia śledzenia wywołań systemowych nie rozumiem:Dlaczego dtruss nie pokazuje mi wyboru wywołania systemowego w tym kodzie JNI?
Tomcat startup fails due to 'java.net.SocketException Invalid argument' on Mac OS X
Wersja krótka: W systemie Mac OS, JDK wykorzystuje select()
zamiast poll()
. Tak więc, jeśli przydzielonych zostanie więcej niż 1024 deskryptorów plików, wywnioskowaliśmy, że wywołanie select()
w NET_Timeout
kończy się niepowodzeniem, czego skutkiem jest wyjątek SocketException z komunikatem "Nieprawidłowy argument". Jednak kiedy wyśledziłem wywołania systemowe, nie widziałem żadnego dowodu na wywołanie systemowe, ani żadnego połączenia, które zawiedzie i ustawia EINVAL, więc zdyskredytowałem to jako potencjalną przyczynę.
ja również nie widzę połączenia z obniżonym przypadku testowego Utworzyłem teraz rozumiem problemu:
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();
}
}
wyniki w tej wyjątku na Mac OS w/JDK 1.7u5 i później:
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)
Dlaczego nie widzę żadnych dowodów select()
(lub jakimkolwiek innym) niedopełnienie nazywają kiedy wykonać test przy użyciu sudo dtruss -a java SelectTest
?
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
W tym przypadku problem nie jest uderzanie limitu CD, to przy użyciu więcej niż 1024 z wybierz połączenie, które jest w obchodzeniu kod Darwin timeout sieci (bsd_close.c). Zobacz powiązane pytanie, aby poznać szczegóły - jest to specyficzne dla Darwina. –