Ich habe ein Buch über Programmierkenntnisse gelesen, in dem der Autor den Befragten fragt: "Wie stürzt man eine JVM ab?" Ich dachte, Sie könnten dies tun, indem Sie eine Endlos-for-Schleife schreiben, die schließlich den gesamten Speicher verbraucht.
Hat jemand eine Idee?
Antworten:
Das, was einer einzelnen "Antwort" am nächsten kommt, ist,
System.exit()
dass die JVM sofort ohne ordnungsgemäße Bereinigung beendet wird. Abgesehen davon sind nativer Code und Erschöpfung der Ressourcen die wahrscheinlichsten Antworten. Alternativ können Sie in Suns Bug-Tracker nach Fehlern in Ihrer Version der JVM suchen, von denen einige wiederholbare Absturzszenarien ermöglichen. Früher kam es bei den 32-Bit-Versionen zu halb-regulären Abstürzen, wenn wir uns dem 4-GB-Speicherlimit näherten (wir verwenden jetzt im Allgemeinen 64-Bit).quelle
Ich würde das Auslösen eines OutOfMemoryError oder StackOverflowError nicht als Absturz bezeichnen. Dies sind nur normale Ausnahmen. Um eine VM wirklich zum Absturz zu bringen, gibt es drei Möglichkeiten:
Für die letzte Methode habe ich ein kurzes Beispiel, das eine Sun Hotspot-VM leise zum Absturz bringt:
Dies führt zu einem Stapelüberlauf im GC, sodass Sie keinen StackOverflowError erhalten, sondern einen echten Absturz einschließlich einer hs_err * -Datei.
quelle
java.lang.OutOfMemoryError: GC overhead limit exceeded
JNI . Tatsächlich ist bei JNI ein Absturz die Standardbetriebsart. Sie müssen besonders hart arbeiten, damit es nicht abstürzt.
quelle
Benutze das:
Diese Klasse muss sich im Boot-Klassenpfad befinden, da sie vertrauenswürdigen Code verwendet. Führen Sie sie daher folgendermaßen aus:
quelle
Field f = Unsafe.class.getDeclaredField( "theUnsafe" ); f.setAccessible( true ); unsafe = (Unsafe) f.get( null );
.Unsafe
ist per Definition "unsicher". Das ist ein bisschen ein Betrüger.getDeclaredField
Trick in JDK 8u131 unter Linux x64, einschließlich Produktionhs_err_pid*.log
von aSIGSEGV
.Unsafe
ist kein Betrug. OP sucht nicht nach einer "sauberen" Lösung für ein Programmierproblem. Er braucht das JVM, um auf die hässlichste Art und Weise abzustürzen. Böse einheimische Dinge zu tun ist das, was dazu führen kann, und genau dasUnsafe
tut es.Ich bin hierher gekommen, weil ich in The Passionate Programmer auch auf diese Frage gestoßen bin von Chad Fowler . Für diejenigen, die keinen Zugriff auf eine Kopie haben, ist die Frage als eine Art Filter / Test für Kandidaten gedacht, die sich für eine Position bewerben, die "wirklich gute Java-Programmierer" erfordert.
Insbesondere fragt er:
Ich habe über 15 Jahre in Java programmiert und fand diese Frage sowohl rätselhaft als auch unfair. Wie andere bereits betont haben, wurde Java als verwaltete Sprache speziell entwickelt, um nicht zum Absturz zu kommen . Natürlich gibt es immer JVM-Fehler, aber:
Wie andere bereits erwähnt haben, ist nativer Code über JNI ein sicherer Weg, um eine JRE zum Absturz zu bringen. Aber der Autor hat speziell in reinem Java erwähnt , das ist also raus.
Eine andere Möglichkeit wäre, die JRE-Scheinbytecodes einzugeben. Es ist einfach genug, einige Müll-Binärdaten in eine .class-Datei zu kopieren und die JRE zu bitten, sie auszuführen:
Zählt das? Ich meine, die JRE selbst ist nicht abgestürzt. Der falsche Code wurde ordnungsgemäß erkannt, gemeldet und beendet.
Dies lässt uns die naheliegendsten Arten von Lösungen übrig, z. B. das Aufblasen des Stapels durch Rekursion, das Auslaufen des Heapspeichers durch Objektzuweisungen oder das einfache Werfen
RuntimeException
. Dies führt jedoch nur dazu, dass die JRE mit einerStackOverflowError
oder einer ähnlichen Ausnahme beendet wird, was wiederum kein wirklicher Absturz ist .Also, was ist noch übrig? Ich würde wirklich gerne hören, was der Autor wirklich als richtige Lösung im Sinn hatte.
Update : Chad Fowler hat hier geantwortet .
PS: Es ist ein ansonsten tolles Buch. Ich nahm es zur moralischen Unterstützung auf, als ich Ruby lernte.
quelle
Dieser Code wird die JVM auf böse Weise zum Absturz bringen
quelle
InternalError
in JDK 1.8. JVM schlägt nicht mehr fehl.Das letzte Mal, als ich es versuchte, würde es das tun:
Erster Teil der generierten Protokolldatei:
quelle
Eine perfekte JVM-Implementierung wird niemals abstürzen.
Um eine JVM zum Absturz zu bringen, müssen Sie neben JNI einen Fehler in der VM selbst finden. Eine Endlosschleife verbraucht nur CPU. Die unendliche Zuweisung von Speicher sollte nur OutOfMemoryError in einer gut erstellten JVM verursachen. Dies würde wahrscheinlich Probleme für andere Threads verursachen, aber eine gute JVM sollte immer noch nicht abstürzen.
Wenn Sie einen Fehler im Quellcode der VM finden und beispielsweise einen Segmentierungsfehler in der Speichernutzung der Implementierung der VM verursachen, können Sie ihn tatsächlich zum Absturz bringen.
quelle
Wenn Sie JVM zum Absturz bringen möchten, verwenden Sie Folgendes in Sun JDK 1.6_23 oder niedriger:
Dies ist auf einen Fehler in Sun JDK zurückzuführen, der auch in OpenJDK gefunden wurde. Dies wird ab Oracle JDK 1.6_24 behoben.
quelle
Kommt darauf an, was du mit Absturz meinst.
Sie können eine unendliche Rekursion durchführen, um den Stapelspeicherplatz zu verringern, aber das wird "elegant" abstürzen. Sie erhalten eine Ausnahme, aber die JVM selbst übernimmt alles.
Sie können JNI auch verwenden, um nativen Code aufzurufen. Wenn Sie es nicht genau richtig machen, können Sie es schwer zum Absturz bringen. Das Debuggen dieser Abstürze macht "Spaß" (glauben Sie mir, ich musste eine große C ++ - DLL schreiben, die wir von einem signierten Java-Applet aus aufrufen). :) :)
quelle
Das Buch Java Virtual Machine von Jon Meyer enthält ein Beispiel für eine Reihe von Bytecode-Anweisungen, die dazu führten, dass die JVM einen Core-Dump ausführte. Ich kann mein Exemplar dieses Buches nicht finden. Wenn jemand da draußen einen hat, schauen Sie bitte nach und posten Sie die Antwort.
quelle
auf winxpsp2 w / wmp10 jre6.0_7
Desktop.open (uriToAviOrMpgFile)
Dies führt dazu, dass ein gespawnter Thread einen nicht gefangenen Throwable auslöst und der Hotspot abstürzt
YMMV
quelle
Defekte Hardware kann jedes Programm zum Absturz bringen. Ich hatte einmal einen App-Absturz, der auf einem bestimmten Computer reproduzierbar war, während er auf anderen Computern mit genau demselben Setup einwandfrei lief. Es stellte sich heraus, dass die Maschine einen fehlerhaften RAM hatte.
quelle
kürzest möglicher Weg :)
quelle
Exception in thread "main" java.lang.StackOverflowError at Test.main
. Ich benutze jdk1.8.0_65Kein Absturz, aber näher an einem Absturz als die akzeptierte Antwort der Verwendung
System.exit
Sie können die JVM durch Aufrufen anhalten
Runtime.getRuntime().halt( status )
Laut den Dokumenten: -
quelle
Hier finden Sie eine ausführliche Erläuterung der Ursachen für den Core-Dump von JVM (dh Absturz): http://kb.adobe.com/selfservice/viewContent.do?externalId=tn_17534
quelle
Wenn Sie so tun möchten, als hätten Sie keinen Speicher mehr, können Sie dies tun
Ich kenne einige Möglichkeiten, um den JVM-Speicherauszug zu einer Fehlerdatei zu führen, indem native Methoden (solche, die eingebaut sind) aufgerufen werden, aber es ist wahrscheinlich am besten, wenn Sie nicht wissen, wie dies zu tun ist. ;)
quelle
Wenn Sie einen Absturz als Prozessabbruch aufgrund einer nicht behandelten Situation definieren (dh keine Java-Ausnahme oder -Fehler), kann dies nicht in Java erfolgen (es sei denn, Sie haben die Berechtigung, die Klasse sun.misc.Unsafe zu verwenden). Dies ist der springende Punkt bei verwaltetem Code.
Typische Abstürze im nativen Code treten auf, indem Zeiger auf falsche Speicherbereiche (Nulladresse oder falsch ausgerichtet) de-referenziert werden. Eine andere Quelle könnten illegale Maschinenanweisungen (Opcodes) oder nicht behandelte Signale von Bibliotheks- oder Kernelaufrufen sein. Beide können ausgelöst werden, wenn die JVM oder die Systembibliotheken Fehler aufweisen.
Zum Beispiel können JITed (generierter) Code, native Methoden oder Systemaufrufe (Grafiktreiber) Probleme haben, die zu echten Abstürzen führen (es kam häufig vor, dass ein Absturz auftrat, wenn Sie ZIP-Funktionen verwendeten und der Speicher knapp wurde). In diesen Fällen startet der Crash-Handler der JVM und gibt den Status aus. Es könnte auch eine Betriebssystem-Kerndatei generieren (Dr. Watson unter Windows und Core Dump unter * nix).
Unter Linux / Unix können Sie leicht einen JVM-Absturz verursachen, indem Sie ein Signal an den laufenden Prozess senden. Hinweis: Sie sollten dies nicht verwenden
SIGSEGV
, da Hotspot dieses Signal abfängt und es an den meisten Stellen erneut als NullPointerException auslöst. Es ist also besser,SIGBUS
zum Beispiel eine zu senden .quelle
JNI ist eine große Quelle für Abstürze. Sie können auch über die JVMTI-Schnittstelle abstürzen, da dies auch in C / C ++ geschrieben werden muss.
quelle
Wenn Sie einen Thread-Prozess erstellen, der unendlich mehr Threads erzeugt (die mehr Threads erzeugen, welche ...), verursachen Sie möglicherweise einen Stapelüberlauffehler in der JVM selbst.
Dies gab mir die Ausgabe (nach 5 Minuten beobachten Sie Ihren Widder)
quelle
Wenn mit "Absturz" ein plötzlicher Abbruch der JVM gemeint ist, würde dies dazu führen, dass die JVM in ihr hs_err_pid% p.log schreibt , können Sie dies auf diese Weise tun.
Setzen Sie das--Xmx-Argument auf einen winzigen Wert und weisen Sie die JVM an, einen Absturz auf outofmemory zu erzwingen:
Um klar zu sein, ohne die zweiten arg oben, würde es führt nur in dem Jvm Abschluss mit einem OutOfMemoryError, aber es wäre nicht „Crash“ oder abrupt abbrechen die JVM.
Diese Technik erwies sich als hilfreich, als ich versuchte, das Argument JVM -XX: ErrorFile zu testen, das steuert, wo ein solches hs_err_pid-Protokoll geschrieben werden soll. Ich hatte diesen Beitrag hier gefunden, als ich versuchte, Wege zu finden, um einen solchen Absturz zu erzwingen. Als ich später feststellte, dass das oben Genannte für mein Bedürfnis am einfachsten ist, wollte ich es hier zur Liste hinzufügen.
Schließlich, FWIW, wenn jemand dies testen kann, wenn er bereits einen -Xms-Wert in Ihren Argumenten festgelegt hat (auf einen größeren Wert als oben), möchten Sie diesen ebenfalls entfernen oder ändern, oder Sie erhalten keinen Absturz, sondern einfach Ein Fehler beim Starten des JVM mit der Meldung "Die anfängliche Heap-Größe wurde auf einen größeren Wert als die maximale Heap-Größe festgelegt". (Das wäre nicht offensichtlich, wenn die JVM als Dienst ausgeführt würde, beispielsweise mit einigen App-Servern. Auch hier hat es mich gebissen, also wollte ich es teilen.)
quelle
Wenn Sie diese Endlosschleife in einen rekursiven Aufruf derselben Funktion ändern, wird eine Stapelüberlaufausnahme angezeigt:
quelle
Ich mache es jetzt, bin mir aber nicht ganz sicher, wie ... :-) JVM (und meine App) verschwinden manchmal einfach komplett. Keine Fehler geworfen, nichts protokolliert. Geht ohne Vorwarnung sofort von der Arbeit zum Nicht-Laufen über.
quelle
Kürzeste? Verwenden Sie die Roboterklasse, um STRG + BREAK auszulösen. Ich habe dies festgestellt, als ich versuchte, mein Programm zu schließen, ohne die Konsole zu schließen (es gab keine Exit-Funktion).
quelle
Zählt das?
Es funktioniert nur unter Linux und unter Java 9.
Aus irgendeinem Grund bekomme ich nicht,
ProcessHandle.current().destroyForcibly();
töte die JVM nicht und wirftjava.lang.IllegalStateException
mit der Meldung Zerstörung des aktuellen Prozesses nicht erlaubt .quelle
Dieses Problem tritt auf, wenn versucht wird, den JVM-Absturz zu replizieren.
Jni funktioniert, muss aber für verschiedene Plattformen optimiert werden. Schließlich verwende ich diese Kombination, um JVM zum Absturz zu bringen
-XX:+CrashOnOutOfMemoryError
long[] l = new long[Integer.MAX_VALUE];
, um das OOM auszulösenDann stürzt JVM ab und generiert das Absturzprotokoll.
quelle
Wenn ein 'Absturz' etwas ist, das das jvm / Programm von der normalen Beendigung abbricht, könnte dies eine nicht behandelte Ausnahme tun.
Es kommt also darauf an, welche Art von Absturz ?!
quelle
ArithmeticException
ist