Die einzige wirkliche Option ist (leider), die JVM so schnell wie möglich zu beenden.
Da Sie wahrscheinlich nicht Ihren gesamten Code ändern können, um den Fehler abzufangen und zu reagieren. Wenn Sie dem OnOutOfMemoryError
nicht vertrauen (Ich frage mich, warum es nicht vfork verwenden sollte, das von Java 8 verwendet wird und unter Windows funktioniert), Sie können zumindest einen Heapdump auslösen und diese Dateien extern überwachen:
java .... -XX:+HeapDumpOnOutOfMemoryError "-XX:OnOutOfMemoryError=kill %p"
Nachdem wir einige Zeit damit experimentiert haben, ist dies die Lösung, die für uns funktioniert hat:
- Fangen Sie in der erzeugten JVM eine
OutOfMemoryError
und wird sofort beendet, wobei der Speichermangelzustand mit einem Exit-Code an die Controller-JVM signalisiert wird. - Überprüfen Sie in der erstellten JVM regelmäßig die Menge des verbrauchten Arbeitsspeichers der aktuellen
Runtime
. Wenn die verwendete Speichermenge nahezu kritisch ist, erstellen Sie eine Flag-Datei, die der JVM des Controllers signalisiert, dass der Speicher nicht ausreicht. Wenn wir uns von diesem Zustand erholen und normal beenden, löschen Sie diese Datei, bevor wir beenden. - Nachdem die steuernde JVM der gegabelten JVM beigetreten ist, überprüft sie den in Schritt (1) generierten Exit-Code und die in Schritt (2) generierte Flag-Datei. Außerdem wird geprüft, ob die Datei
hs_err_pidXXX.log
existiert und enthält die Zeile "Out of Memory Error". (Diese Datei wird von Java generiert, falls es abstürzt.)
Erst nach der Implementierung all dieser Überprüfungen konnten wir alle Fälle behandeln, in denen der gegabelten JVM der Arbeitsspeicher ausging. Wir glauben, dass wir seitdem keinen Fall verpasst haben, in dem dies passiert ist.
Das Java-Flag -XX:OnOutOfMemoryError
wegen des Fork-Problems nicht verwendet wurde, und -XX:+HeapDumpOnOutOfMemoryError
wurde nicht verwendet, weil ein Heap-Dump mehr ist, als wir brauchen.
Die Lösung ist sicherlich nicht das eleganteste Stück Code, das je geschrieben wurde, aber hat den Job für uns erledigt.