2

在主线程生成一个帧后,它会死掉,但由于事件调度程序机器 JVM 创建的非守护线程没有退出。但是我的问题是,一旦主线程结束,它的堆栈也将消失,因此框架的引用将不再存在,因此可以随时对框架对象进行垃圾收集。但这没有发生,为什么?

4

1 回答 1

3

正如您所注意到的:Swing 事件线程是一个非守护线程,因此在它运行时,它会阻止应用程序退出。

但是我的问题是,一旦主线程结束,它的堆栈也将消失,因此框架的引用将不再存在,因此可以随时对框架对象进行垃圾收集。

这不是使对象被标记为被 GC 的原因。活动线程中不需要对它的活动引用,并且由于 EDT,此条件尚未满足。

当不再有对该对象的引用时,该对象就有资格进行垃圾回收。当变量超出范围时,通常会删除变量中保存的引用。或者,您可以通过将变量设置为特殊值 null 来显式删除对象引用。请记住,一个程序可以对同一个对象有多个引用;在对象有资格进行垃圾回收之前,必须删除对对象的所有引用。参考


编辑
您在评论/我的回复中声明:

我的意思是说第一次单击按钮时,它的事件将进入事件队列,从那里事件调度程序机器将为该事件创建一个 EDT,该事件将执行执行的操作方法。

不会。只要显示 GUI,就会创建 Swing EDT。因此,如果在 GUI 中看到该按钮,则它的 GUI 正在创建并显示在正在运行的 EDT 上。按下按钮时不会创建 EDT。相反,Runnables 可能会在事件队列中排队等待由 EDT 处理。

现在执行完成后说我再次按下按钮,事件再次进入事件队列,现在机器必须启动另一个线程,因为同一个线程不能启动两次。

再次没有。只有一个 EDT 持续运行。除非您显式创建并启动一个新线程,例如 vianew Thread(...).start()或调用execute()SwingWorker 对象,否则不会创建新线程。

于 2013-07-20T18:14:43.893 回答