Gelegentliche UnterbrechungException beim Beenden einer Swing-Anwendung
Ich habe vor kurzem aktualisiert mein computer auf eine leistungsfähigere, mit einem quad-core-hyperthreading-Prozessor (i7), somit viel echte Parallelität zur Verfügung. Jetzt bin ich gelegentlich immer folgende Fehler beim beenden (System.exit(0)
) ein Programm (mit Swing GUI), die ich entwickle:
Exception while removing reference: java.lang.InterruptedException
java.lang.InterruptedException
at java.lang.Object.wait(Native Method)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:118)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:134)
at sun.java2d.Disposer.run(Disposer.java:125)
at java.lang.Thread.run(Thread.java:619)
Gut, da es anfing zu passieren, mit einem mehr Parallelität-fähiger hardware, und es hat zu tun mit threads, und es passiert gelegentlich, dass es offensichtlich eine Art von timing-Sache. Aber das problem ist, dass der stack trace ist so kurz. Alle die ich habe, ist die Liste oben. Es nicht mein eigener code, so dass es etwas schwer zu erraten, wo der Fehler ist.
Hat jemand so etwas ähnliches erlebt, dies vor? Irgendwelche Ideen, wie Sie beginnen, es zu lösen?
Edit: Da das beenden einer Swing-Anwendung mit System.exit(0)
werden kann "unrein", aber ich möchte nicht den main-frame zu EXIT_ON_CLOSE
weil ich will, um sicherzustellen, dass es nichts kritisches vor sich geht, wenn die Anwendung beendet wird, habe ich noch einen Mechanismus, so dass es führt die main-frame-s dispose()
- Methode vor dem Aufruf System.exit(0)
. So sollte es sein, ziemlich sauber, aber die Ausnahme passiert immer noch. Es geschieht nach den System.exit(0)
genannt worden; dispose()
funktioniert ohne Probleme. Das heißt, es muss aus einem shutdown-hook:
mainFrame.dispose(); //No problem! After this returns, all visible GUI is gone.
//In fact, if there were no other threads around, the VM could terminate here.
System.exit(0); //Throws an InterruptedException from sun.java2d.Disposer.run
Ich habe sogar explizit Entsorgung alle Window
s, indem die Schleife durch Window.getWindows()
array (es enthält herrenlos Dialog
s und so), aber es machte keinen Unterschied. Dieses Problem scheint wenig zu tun zu haben, die mit "Reinheit" (also explizit die Freigabe native Bildschirm-Ressourcen vor dem beenden). Es ist etwas anderes, aber was?
Edit 2: Einstellung die default-close-operation zu EXIT_ON_CLOSE
kein Unterschied gemacht. http://www.google.com/search?q=sun.java2d.Disposer.run(Entsorger.java:125) findet ein paar bug-reports, so dass dies vielleicht in der Tat ein bug in der Sonne Java2D-Implementierung. Ich könnte mir vorstellen, dass bugs wie dieser gehen kann lose für eine lange Zeit, denn Sie sind ziemlich harmlos in der Praxis; eine Ausnahme von einem shutdown-hook kaum weh tut jemand anderes. Gegeben, dass dies geschieht in einem GUI-app, die Ausnahme wird nicht einmal bemerkt, es sei denn, die stderr
richtet sich an eine Konsole oder log.
InformationsquelleAutor der Frage |
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ihren Entsorger blockiert, in einem Aufruf von remove () entfernen (die nächste Plattform native Ressource). Dies bedeutet, dass die Entsorger thread (ein daemon-thread) nicht Herunterfahren natürlich, wenn die VM beendet (was Sie erwarten sollten, da Sie beenden es über System.exit()).
Haben Sie eine nicht-daemon-thread in Ihrer Anwendung, die halten Sie die VM beenden, wenn alle Ihre swing-Fenster wurden entsorgt.
Lösung: finden Sie es und führen es zu beenden.
Normalerweise eine swing-Anwendung ordnungsgemäß beendet, wenn alle seine swing-Fenster wurden entsorgt, zum Beispiel, dieses Programm öffnet ein Fenster, beenden Sie dann, sobald es geschlossen ist (alle mit kein Aufruf System.exit()):
Können Sie auch versuchen, läuft der garbage collector vor dem verlassen, nur für kicks.
InformationsquelleAutor der Antwort
Möchte bis-Abstimmung in dieser, aber ich brauche mehr rep. Diese Lösung funktionierte für mich, obwohl ich nicht finde die Erklärung, warum, und mein Kollege sagt auch das es keinen Sinn macht.
1.7 habe ich Schaukel und eine app, die ich erstellt habe, es liest eine Datei, ordnet die Inhalte und dann die Ausgaben in eine Datei. hat einen Lauf-und beenden-Taste. verwendet die preferences-API, writer, reader, und ein paar andere Dinge. Beim öffnen und schließen der app (ohne
System.gc()
) sofort nur noch zwei mal hintereinander zurück das gleiche Exception wie oben angegeben. aber mitSystem.gc()
Recht vordispose()
ich Schaffe es nicht, die Ausnahme wieder.InformationsquelleAutor der Antwort
System.exit() ist wahrscheinlich nicht die sauberste Art und Weise der Schließung eines Swing basierten app
Können Sie nicht setzen Sie Ihre main-frame zu EXIT_ON_CLOSE:
Dann unsichtbar?
Verwandte Q hier; System.exit(0) in java
InformationsquelleAutor der Antwort tim_yates
Frage ich mich, ob es nicht zu diesem bug :
Java-Bug 6489540
Grundsätzlich bedeutet es, dass, falls Java2D verwendet wird, wenn eine InheritableThreadLocal-Objekt existiert, oder eine benutzerdefinierte contextClassLoader vorhanden ist, werden Sie gefangen genommen und für immer Leben verursachen Speicherlecks und möglicherweise diese Art von seltsam Schlösser.
Wenn dies der Fall ist ein workaround wäre, die zum auslösen eines Java2D-Aktion auf dem Haupt-thread (also sofort, wenn die Anwendung gestartet wird), so dass die DisposerThread Leben in einer "squeky sauberen" Umgebung. Es wird gestartet, indem eine statische Initialisierer also einfach eine dummy-load für ein java2d-Ressource und befreiend es sein würde, genug, um eine DisposerThread, die nicht hängen, um die unerwünschte Zeug.
InformationsquelleAutor der Antwort
Ich glaube, ich habe gefunden, wo der Fehler herkommt !
Wenn Sie eine einfache java-Anwendung mit Exit Untermenü in ein Datei-Menü...
Gibt es einen shortcut zum aktivieren des exit-Action...Diese Verknüpfung muss, macht eine kreisförmige link oder sowas...
Gibt es die Lösungen :
Zunächst ist optional zu bekommen, alles klar:
Diese Schnittstelle implementiert "WindowListener" aus dem Hauptfenster.
Beim Bau der main-Fenster dies :
implementiert die Funktionen aus dem interface :
Nach, dass Sie müssen vorsichtig sein, über dein Abkürzungen !
Sie 'll haben, entfernen Sie die Aktion aus dem Exit-Menü, um es zu verwalten mit einem actionPerformed :
Ich nicht erklären, warum, aber es funktioniert für mich... ich denke, dass es eine Art von Zirkelbezügen...
Hoffe, Ihnen zu helfen.
See ya.
InformationsquelleAutor der Antwort
Ich habe das gleiche Problem ( Java 6 ).
Ich bemerkte ein unknwon Sonne.das awt.Bild.ImageFetcher thread in den debugger.
Ich denke, es kommt von mir mit JButtons mit Icons.
Die ImageFetcher thread verschwindet nach 2 Sekunden.
Wenn die ImageFetcher thread nicht mit meinem programm beendet gerade fein.
InformationsquelleAutor der Antwort
Es klingt wie Sie haben einen thread laufen, der die noch nicht beendet, wenn Sie zu beenden. Vor allem, der thread wait()ing, und die Methode wirft eine Ausnahme unterbrochen, wenn Sie versuchen, beenden Sie den Faden, während es läuft. Ich immer hintergrund-threads laufen als Daemons, die vielleicht helfen, wie gut.
Ich würde Folgendes tun, die in Ihrem JFrame:
Manuell durch brechen aus der Schleife, können Sie die wait-Methode zu beenden (hoffentlich bist du nicht warten unendlich lange, sind Sie? Wenn Sie sind, möchten Sie vielleicht, um erneut zu prüfen, wie Sie die Verwendung von threads) und dann zu einem Punkt in Ihrem code, wo Sie sicher zu brechen - sicher, weil Sie kodiert es zu tun - und dann wird der thread beendet, lassen Sie die Anwendung beenden, einfach nur gut.
Update
Vielleicht sind Sie mit dem event-dispatch-thread unpassend, irgendwo, und es wartet schon/noch für Sie arbeiten, wenn Sie versuchen, zu beenden? Der dispatcher thread sollte so wenig Arbeit wie möglich, und sollte die übergabe etwas komplexer aus einem anderen thread, so schnell wie Sie können. Ich gebe zu, ich bin stechende, um in der Dunkelheit ein wenig, aber ich bin geneigt zu denken, es ist kein bug, vor allem wenn man bedenkt, dass Sie begann es zu merken-auf eine leistungsfähigere Maschine, das zu mir schreit "Race-Condition!" nicht Java Fehler.
InformationsquelleAutor der Antwort
Dort ist der Fehler manchmal wieder, aber dieses scheint gut zu funktionieren :
InformationsquelleAutor der Antwort
Ich hatte das gleiche problem, und fand, dass ich musste einfach einen Rahmen versteckt im hintergrund (ich hatte es die Sichtbarkeit auf false gesetzt). Wenn ich sicher zu nennen .dispose() auf meine versteckten frame und dann .dispose() auf meinem mainFrame-ich hatte keinen Grund zu nennen-System.exit(0), die Anwendung einfach selbst gereinigt und Herunterfahren. Mein code ist Scala, aber die Idee ist die gleiche.
InformationsquelleAutor der Antwort
Wenn Sie wurden mit der Swing App Frameworkkönnte man überschreiben
Application.exit()
zu Bereinigung durchführen, oder fügen Sie einExitListener
als gut. Ansonsten könnten Sie auch einen shutdown-hook,Runtime.getRuntime().addShutdownHook()
zu Ihrer app.InformationsquelleAutor der Antwort
Threads in java nur dann beenden, wenn alle der run () - Methode die Ausführung beendet. Sonst wirst du immer diese Thread-erweiterte Objekte in VM rumgespielt. Sie haben bis zum Ende alle Fäden vor, die Anwendung zu beenden.
Bedenken Sie auch, dass, wenn Sie erstellen Sie Ihre jFrame Sie starten einen Thread (CURRENT_THREAD glaube ich)
InformationsquelleAutor der Antwort
War ich immer eine ähnliche Fehlermeldung und irgendwie ist dies für mich gearbeitet:
InformationsquelleAutor der Antwort
Versuchen, EventQueue.invokeLater() schließen Sie Ihre Swing.
InformationsquelleAutor der Antwort
Scheint dies ein bug behoben, der die Java 1.7.
Konfiguriert mein Eclipse zum ausführen in jdk 1.7 und der Fehler ging Weg.
Yoav
InformationsquelleAutor der Antwort
Ich lief einfach in diesen Fehler mit Datenbanken. Das problem war, dass die Verbindung zur Datenbank nicht geschlossen wurde. Ich löste dies durch den folgenden code :
Nur werfen dies draußen für andere Menschen...
InformationsquelleAutor der Antwort
Wenn Sie mit swing-Anwendung dann die erste call-System.gc() und rufen Sie die dispose () - Methode.
Ich denke, es wird gut funktionieren.. ich benutze diese auch.
InformationsquelleAutor der Antwort