Wie kann ich die JVM beenden auf JEDEM OutOfMemoryException, auch wenn böse Menschen versuchen, Sie zu fangen
Einer OOME ist der Klasse von Fehlern, die im Allgemeinen sollten Sie sich nicht erholen. Aber wenn es begraben ist, in einem thread, oder jemand fängt, ist es möglich, für eine Anwendung zu erhalten in einem Staat, von dem Sie nicht verlassen, aber ist das nicht sinnvoll. Irgendwelche Vorschläge, wie dies zu verhindern ist, auch im Angesicht der Verwendung von Bibliotheken kann die dummerweise versuchen, Sie zu fangen Throwable oder Error/OOME? (also keinen direkten Zugriff auf den Quellcode ändern)
- Warum sollten Sie nicht wiederhergestellt werden? Ein OOME ist nicht etwas, das passiert durch einen Fehler bei der Programmierung (wie ein null-Zeiger oder ungültiges argument), sondern weil auf eine unvorhergesehene situation zur Laufzeit, die ein wirklich stabiles Anwendung sollte versuchen, zu überleben. Natürlich, es wäre klug, sich zu informieren Administratoren, wenn es passiert (in einer server-app), so können Sie schauen in es.
- Ich bin ziemlich sicher, dass das, was Sie vorschlagen, ist genau das, was die Menschen NICHT tun sollte (außer in sehr außergewöhnlichen Umständen). Lesen Sie die java-docs auf der es weitere details.
- Arbeiten Sie nicht mit dieser Art von Menschen?
- siehe stackoverflow.com/questions/333736/...
Du musst angemeldet sein, um einen Kommentar abzugeben.
Lösung:
Definition: Ausführen von benutzerdefinierten Befehlen, wenn ein OutOfMemoryError wird zuerst geworfen. (Eingeführt in 1.4.2 update 12, 6)
Sehen http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html
Ein Beispiel, das tötet den Laufenden Prozess:
kill -9
-ing die JVM möglicherweise haben böse Nebenwirkungen.-XX:OnOutOfMemoryError="kill -9 $PPID"
.Wenn einige Stück code in Ihrer Anwendung JVM entscheidet, dass er versuchen will zu fangen, OOMEs und versuchen, sich zu erholen, es ist (leider) nichts, dass du tun kannst, um es zu stoppen ... abgesehen von AOP Heldentaten, die wahrscheinlich unpraktisch, und die sind definitiv schlecht für Ihre Anwendung performance und Wartbarkeit. Abgesehen davon, dass die beste Sie tun können, ist den Stecker ziehen, die auf die JVM durch die Verwendung einer "OnOutOfMemoryError" Haken. Siehe Antwort oben: https://stackoverflow.com/a/3878199/139985/
Im Grunde, Sie müssen Vertrauen in die anderen Entwickler nicht, dumme Dinge zu tun. Andere dumme Dinge, die Sie wahrscheinlich sollte nicht versuchen, gegen zu verteidigen umfassen:
System.exit()
tief in eine Bibliothek Methode,Thread.stop()
und Freunde,In der Praxis, der Weg zur pick-up-Probleme, wie dies in code geschrieben von anderen Menschen, ist die Verwendung der code-Qualität-checker, und führen Sie code-reviews.
Wenn ein problem mit 3rd-party-code, melden Sie es als BUG (was es wahrscheinlich auch ist) und wenn Sie nicht übereinstimmen, starten Sie auf der Suche nach alternativen.
Für diejenigen, die nicht bereits wissen, gibt es eine Reihe von Gründen, warum es eine schlechte Idee, zu versuchen sich zu erholen von einer OOME:
Die OOME haben könnte geworfen worden, während der aktuelle thread wurde in der Mitte der Aktualisierung einige wichtige Daten Struktur. Im Allgemeinen Fall wird der code, der fängt diese OOME hat keine Möglichkeit dies zu wissen, und wenn er es versucht auf "wiederherstellen" es ist ein Risiko, das die Anwendung wird auch weiterhin mit Schäden an der Struktur der Daten.
Wenn die Anwendung multi-threaded ist, gibt es eine chance, dass OOMEs haben könnte, wurde geworfen in anderen threads als gut, was die Erholung noch schwieriger.
Sogar, wenn Sie die Anwendung wiederherstellen können, ohne Datenstrukturen in einem inkonsistenten Zustand, der die Wiederherstellung kann nur bewirken, dass die Anwendung limp entlang für ein paar Sekunden mehr und dann OOME wieder.
Es sei denn, Sie legen Sie die JVM-Optionen entsprechend, eine JVM, die hat fast run out of memory neigt dazu, viel Zeit zu verbringen, Müll sammeln in einem vergeblichen Versuch, zu tun zu halten. Versuch der Wiederherstellung von OOMEs ist wahrscheinlich verlängern die Qual.
Erholt sich von einer OOME tut nichts zur Adresse die Ursache ist typischerweise ein Speicher-Leck, schlecht konzipiert (d.h. Speicher verschwenderisch) Daten-Struktur, und/oder starten Sie die Anwendung mit einem Haufen, der ist zu klein.
find
undgrep
sollte ausreichen, um den fehlerhaften code suchen. (Ich nehme an, er hat den source code zugreifen. Wenn nicht er, es könnte ein bisschen mehr ... mit einem decompiler.)Error
s und metaphorisch zieht den Stecker auf der JVM.Bearbeiten
OutOfMemoryError.java
hinzufügenSystem.exit()
in seine Konstruktoren.kompilieren. (interessanterweise javac
kümmert sich nicht, es ist im Paket
java.lang
)fügen Sie die Klasse in JRE
rt.jar
nun jvm wird diese neue Klasse. (böse lacht)
Dies ist eine Möglichkeit, möchten Sie vielleicht bewusst zu sein. Ob es eine gute Idee, oder auch legal, ist eine andere Frage.
java.lang
? Ja, es gibt security checks zu stoppen, eine normale Anwendung JAR (etc) ersetzt werden, "java.lang.*" etc-Klassen, aber diese müssen durchgesetzt werden, die von der Klasse loader / security manager. (Wenn Sie verlassen sich auf die Java-compiler zu tun, der Durchsetzung, wäre es relativ einfach, Sie zu untergraben.)Eine weitere Sache, die ich mir vorstellen könnte (obwohl ich nicht weiß, wie es zu realisieren) wäre, um führen Sie Ihre app in eine Art debugger. Mir ist aufgefallen, dass mein debugger beendet die Ausführung, wenn eine Ausnahme geworfen wird. 🙂
So kann man Sie verwirklichen könnte, eine Art der Ausführung, die Umwelt zu erreichen.
Wie über den Fang OOME Sie sich in Ihrem code und
System.exit()
?Starten Sie Ihre java-Programm mit Java Service Wrapper mit einem OutOfMemory-Detection Filter. Allerdings setzt dies Voraus, dass die "schlechten Menschen" sind schön genug, um log den Fehler 🙂
Eine Möglichkeit, die ich lieben würde, zu sein, Sprach aus, ist ein dummer thread das ist job ist, etwas zu tun auf dem heap. Sollte es erhalten OOME - dann beendet die ganze JVM.
Bitte sagen Sie mir, das ist nicht sinnvoll.
Könnten Sie die MemoryPoolMXBean benachrichtigt werden, wenn ein Programm mehr als einen Satz heap Schwelle.
Habe ich noch nicht verwendet, aber es mir möglich sein sollte, heruntergefahren auf diese Weise, wenn der Verbleibende Speicher wird geringer, indem eine Zuordnung Schwelle und aufrufen von System.exit (), wenn Sie die Benachrichtigung erhalten.
Einzige, was ich denken kann, ist mit AOP zu wickeln jede einzelne Methode (Vorsicht vor Regel java.*) mit einem try-catch für OOME und wenn dem so ist, anmelden etwas und Ruf-System.exit() in den catch-block.
Nicht eine Lösung, ich würde Sie anrufen und elegant, aber...