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

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

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

现在问题:

  1. 有谁能告诉我究竟发生了什么?为什么Webstart会离开僵尸JVM?
  2. 有没有办法在不停止JVM的情况下显式释放Webstart资源?
  3. 我一直认为调用System.exit()会鼓励你不要释放你的资源并依赖操作系统来清理你(如果你以后重用代码会导致令人讨厌的意外)的草率做法......我错过了什么吗?
  4. 另见后续问题,用于检测该应用是否已由Webstart启动。

有帮助吗?

解决方案

由于WebStart中的错误,是的。 WebStart启动“安全线程”。因为它与EDT的相互作用。此SecureThread可防止在处理所有窗口和AWT资源时自动终止Java进程。

有关详细信息,请参阅 http://www.pushing-pixels.org/?p = 232

其他提示

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

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

Webstart启动控制台窗口(您可以禁用它)。控制台窗口用于查看webstart进程的stdout / err以及基本日志/调试,但具有创建顶级AWT / Swing窗口的副作用。由于AWT / EDT仅在放置LAST窗口时结束,因此控制台窗口会占用您的应用程序。您可能应该调用System.exit()以100%确定您的应用程序退出(除非您可以保证某个客户端配置,关闭webstart控制台)

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

我在网络启动时遇到了同样的问题。如果我关闭java控制台,该过程不会挂起。来自Sun的任何已知错误ID?

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top