Ich bin der Idiot, der seit Jahren Java macht und vergessen hat zu schließen und einen Fehler verursacht hat.
Bei der Durchführung kontinuierlicher Auslastungstests auf einem in der Entwicklung befindlichen Server wurde das Verhalten der Anwendung im Laufe der Zeit merkwürdig. Es gab kein Problem mit der CPU- oder Speichernutzung, und die Ursache blieb unbekannt. Wenn ich sie jedoch ein oder zwei Wochen lang verließ, starb die Anwendung mit einem Fehler wie "Datei kann nicht mehr geöffnet werden" im Protokoll. .. Nachdem die Anwendung die Anzahl der geöffneten Dateideskriptoren überprüft hatte, wurde bestätigt, dass die maximale Anzahl der pro Prozess geöffneten Dateideskriptoren erreicht wurde.
return Files.list(Paths.get(dirPathStr)).map(path -> path.getFileName().toString())
.collect(Collectors.toSet());
Der betreffende Code ist oben. Eine Methode, die mithilfe der Stream-API eine Liste von Dateinamen in einem Verzeichnis zurückgibt, das von Files.list ()
geöffnete Verzeichnis jedoch nicht geschlossen wird.
Selbst wenn ich vergesse zu schließen, denke ich, dass der Speicher selbst von GC freigegeben wird, die Dateideskriptoren jedoch nicht freigegeben werden, sodass die Anzahl der Dateideskriptoren bei jeder Ausführung weiter zunimmt.
Wenn Sie Eclipse für die Entwicklungsumgebung (Scannerklasse usw.) verwenden und vergessen, die Instanz der Klasse zu schließen, die die Datei öffnet, werden Sie gewarnt, aber (ab Eclipse 4.7) der obige Code warnt Sie nicht. Warum……
try (Stream<Path> paths = Files.list(Paths.get(dirPathStr))) {
return paths.map(path -> path.getFileName().toString()).collect(Collectors.toSet());
}
Ich habe versucht, es richtig zu schließen. Die Zunahme der Dateideskriptoren tritt nicht mehr auf und die Anwendung funktioniert einwandfrei.
Lektionen unten
Recommended Posts