Я недавно обновил свой компьютер до более мощного, с четырехъядерным процессором Hyper-Threading (i7), таким образом, было много реального параллелизма. Теперь я иногда получаю следующую ошибку при выходе (System.exit(0)
) из приложения (с графическим интерфейсом Swing), которое я разрабатываю:
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)
Что ж, учитывая, что это начало происходить с аппаратным обеспечением с более высокой степенью параллелизма, оно имеет отношение к потокам, и иногда это происходит, очевидно, это какая-то временная вещь. Но проблема в том, что трассировка стека такая короткая. Все, что у меня есть, это список выше. Он вообще не включает в себя мой собственный код, поэтому довольно сложно догадаться, где ошибка.
Кто-нибудь испытывал что-то подобное раньше? Есть идеи, как начать ее решать?
Редактировать: Поскольку выход из приложения Swing с System.exit(0)
может быть «нечистым», но я не хочу устанавливать основной фрейм на EXIT_ON_CLOSE
, потому что я хочу убедиться, что ничего критического продолжая работу при выходе из приложения, я добавил механизм, чтобы он выполнял метод dispose()
основного фрейма перед вызовом System.exit(0)
. Так что теперь это должно быть довольно чисто, но случайное исключение все же случается. Это происходит после того, как System.exit(0)
был вызван; dispose()
работает без проблем. То есть, это должно происходить от отключающего крюка:
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
Я даже пытался явно удалить все Window
s, просматривая массив Window.getWindows()
(он содержит Dialog
s без владельца и тому подобное), но это не имело никакого значения. Эта проблема, похоже, не имеет ничего общего с «чистотой» (то есть явным освобождением ресурсов собственного экрана перед выходом). Это что-то еще, но что?
Редактировать 2: Установка операции закрытия по умолчанию на EXIT_ON_CLOSE
не изменила. http://www.google.com/search?q=sun.java2d.Disposer.run(Disposer.java:125) находит несколько отчетов об ошибках, так что, возможно, это действительно ошибка в реализации Sun Java2D. Я мог бы предположить, что подобные ошибки могут оставаться незафиксированными в течение длительного времени, потому что они довольно безопасны на практике; исключение из крюка отключения вряд ли повредит кому-либо еще. Учитывая, что это происходит в приложении с графическим интерфейсом, исключение даже не замечается, если stderr
не направлен на консоль или журнал.