【问题标题】:Do I need to free Swing components before letting them get garbage collected?在让 Swing 组件被垃圾收集之前,我是否需要释放它们?
【发布时间】:2008-11-26 13:23:58
【问题描述】:

我使用外部资源,例如文件或数据库连接,我需要在放开它们之前关闭它们。

我需要对 Swing 组件做同样的事情吗?如果是那怎么办?

【问题讨论】:

    标签: java swing


    【解决方案1】:

    通常情况下,您不需要在处理完对象后处理它们(尽管将对它们的引用设置为 null 可以让它们更快地被 GC)。但是,AWT 和 Swing 对象分配了一些需要释放的本机资源。此外,AWT 线程将窗口视为顶级对象,防止它们被垃圾回收和 JVM 终止。

    因此,当您使用完窗口后,您需要处理它,这会释放它已分配的本机资源。一种方法是调用Window.dispose()。但是,更好的选择是在初始化每个根窗口时调用JFrame.setDefaultCloseOperation()。如果您传递它 DISPOSE_ON_CLOSE 它会在用户关闭窗口时自行处理。当最后一个这样的窗口关闭时,AWT 线程将停止阻塞并允许 JVM 关闭(假设您没有任何其他异常线程在运行)。或者,您可以将它传递给 EXIT_ON_CLOSE,这将导致您的窗口调用 System.exit(),它告诉 JVM 您的应用程序已完成并正常终止。

    【讨论】:

    • 如果我只去掉 JPanel 的一些控件以便放其他东西怎么办?无需关闭整个窗口。然后呢?
    • OP 在这里有一条未答复的评论,我也想知道。 JPanel 需要清理吗?
    【解决方案2】:

    曾经有人教导说,您必须断开所有侦听器的连接,否则它们将充当对 Swing 组件的引用。但我被告知这不再是问题。

    【讨论】:

    • 视情况而定。如果您的组件与您注册侦听器的组件同时或持续终止,则不需要任何特殊操作,无法访问的引用循环将自动被 GC'd。但是,如果您的组件可能在您侦听的组件或服务仍然存在的情况下关闭/丢弃,您的侦听器将成为内存泄漏,并且可能会阻止您的视图、模型和任何其他对象的 GC那个听众。取消注册比您自己的生命周期更长的服务或组件的侦听器非常重要。
    【解决方案3】:

    如果没有对它们的引用,则会自动对对象进行垃圾回收。您不必像对待外部资源那样对待 Swing 组件。但是,如果您有一个以后不需要的组件,您可以将对该组件的任何引用设置为 null。

    JPanel p = new JPanel();
    p = null;
    

    将 p 设置为 null 不会删除对象,但会删除对该对象的任何引用,因此下次垃圾收集器通过时会拾取它。

    尽管不存在对该组件的其他引用,但您必须小心。

    【讨论】:

    【解决方案4】:

    应处置窗口(包括对话框和框架)。如果您创建 (AWT) Graphics 对象,那么它们也应该被处理掉(但通常是在本地处理,例如 paintComponent 方法)。

    如果您有一个侦听器来从长期存在的源更新短期目标,那么您应该在丢弃目标之前将其删除。有一个巧妙的技巧,监听器使用WeakReference 指向目标,这样它就可以在引用消失(并且触发事件)时取消注册。

    【讨论】:

      猜你喜欢
      • 2011-08-20
      • 1970-01-01
      • 2021-02-16
      • 1970-01-01
      • 1970-01-01
      • 2016-10-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-11
      相关资源
      最近更新 更多