8

最近我将一个 Swing 应用程序转换为 Webstart。这个过程非常简单,但我发现在我关闭所有窗口后,我的应用程序的 JVM 并没有终止。线程转储显示有几个非守护线程,特别是 Swing 的 EDT、AWT 和几个 websart 相关线程。

实际使用的策略是每个窗口在创建时递增一个计数器,在关闭时递减一个。默认关闭操作是 DISPOSE_ON_CLOSE。当计数器达到零时,我停止所有线程池并释放所有 JNI 资源。

当我从 bat 文件(相同的 JAR)启动应用程序时,它在所有窗口都关闭时正常终止,所以我认为问题与 Webstart 有关。

现在的问题:

  1. 谁能告诉我到底发生了什么?为什么 Webstart 会留下僵尸 JVM?
  2. 有没有办法在不停止 JVM 的情况下显式释放 Webstart 资源?
  3. 我一直认为调用 System.exit() 会鼓励草率的做法,即不释放您的资源并依赖操作系统在您之后进行清理(如果您稍后重用代码,这可能会导致令人讨厌的意外)......我错过了什么吗?

另请参阅后续问题以检测 Webstart 是否已启动该应用程序。

4

5 回答 5

6

由于 WebStart 中的错误,是的。WebStart 为自己的目的启动了一个与 EDT 交互的“安全线程”。此 SecureThread 可防止在释放所有窗口和 AWT 资源时自动终止 Java 进程。

欲了解更多信息,请参阅http://www.pushing-pixels.org/?p=232

于 2008-10-17T19:36:16.547 回答
1

AWT EDT 通常是罪魁祸首。几年来,当没有未处理的窗口时,它有一些关闭的逻辑。但是,泄漏问题经常出现,包括在 AWT 和 Swing 的实现中。因此,我强烈建议在生产版本中使用 System.exit(您可能希望将其排除在外以进行一些测试以检测泄漏)。

当没有系统窗口(控制台、javax.jnlp 服务和其他对话框)显示时,WebStart 线程应该都是守护进程。

于 2008-10-17T13:22:48.813 回答
0

Webstart 启动控制台窗口(您可以禁用它)。控制台窗口用于查看 webstart 进程的标准输出/错误以及基本日志/调试,但具有创建顶级 AWT/Swing 窗口的副作用。由于 AWT/EDT 仅在最后一个窗口被释放时才结束,因此控制台窗口正在阻止您的应用程序。您可能应该调用 System.exit() 以 100% 确保您的应用程序退出(除非您可以保证某个客户端配置,webstart 控制台已关闭)

于 2008-10-17T13:09:01.243 回答
0

考虑使用 jconsole 附加并查看 JVM 正在做什么。

于 2009-02-17T19:45:37.577 回答
0

我在使用 web start 时遇到了同样的问题。如果我关闭 java 控制台,进程不会挂断。来自 Sun 的任何已知错误 ID?

于 2009-03-03T15:27:19.860 回答