Hallo zusammen,
ich kämpfe gerade mit folgendem Problem und finde keine Antwort:
Wir haben hier eine Java Consolenanwendung (läuft unter SuSE Linux Enterpreise Server 11), welche einen proprietären Dienst über einen Socketserver zur Verfügung stellt.
Die Anwendung belegt auch nach Tagen nur rund 7MB von einem maximal erlaubten Heap von rund 200MB.
Das Problem das wir nun haben:
Nach unbestimmter Zeit gehen dem Prozess die Filedescriptoren (FD) aus. Wenn man in /proc//fd schaut, dann gibt’s da nach 24 Stunden locker mal über 1000 Socket-FDs, während netstat nur ~40 Socketverbindungen für den Prozess anzeigt.
Wenn ich über JConsole von außen manuell den GC triggere, so bricht die Anzahl der offenen Socket FDs wieder auf rund 110, während die Anzahl der Socketverbindungen noch bei rund 40 liegt.
Mit einem Profiler hab ich schon die Sache untersucht: Sieht, mal abgesehen davon dass sich immer viele Socket-Objekte anhäufen, die dann vom GC wieder abgerüumt werden können, nicht besonders wild aus. Alles im grünen Bereich.
Meine Vermutung ist jetzt:
Der Dienst macht in kurzer Zeit sehr viele Verbindungen auf und wieder zu. Aber der Heap ist damit quasi gar nicht belastet, weshalb sich verdammt viele, unbenutzte Socketobjekte (und daran auch FDs) anhäufen. Der Java Seite macht das nix. Aber auf nativer Seite gammeln mit der Zeit zu viele FD rum, so dass das Limit von 4k FD nach 1-2 Tagen erreicht ist und nix mehr geht.
Triggere ich den GC manuell, so wird abgeräumt. Aber von alleine scheint das, aufgrund des wirklich niedrigen Heap-Bedarfs zu selten zu passieren.
Was sagt ihr zu dieser These? Wie verhindert man das, ohne selbst den GC hin und wieder aufzurufen?!
Gruß
Alex
P.S. Verwenden aktuell noch Java 1.7.0 Update 10. EIn Update auf Update 45 steht noch aus, dauert aber noch, da noch viel zu testen ist.