【问题标题】:How do I get AppContext to release AWT components so they can be garbage collected?如何让 AppContext 释放 AWT 组件以便它们可以被垃圾收集?
【发布时间】:2011-08-20 10:29:11
【问题描述】:

我的团队正在分析我们的 Swing 应用程序,以确保在不再使用所有内容时对其进行垃圾收集。我们遇到了一个奇怪的问题。

我们只是打开一个新窗口 (JFrame) 并关闭它。此框架包含一个EmptyPanel 类(其中包含一条说明没有数据的短消息)和一个自定义JMeunBar 类。我们根本不与之交互 - 只需立即关闭窗口。

然后,我们强制进行垃圾回收并进行堆转储。

根据堆转储分析,JMenuBar 没有被垃圾收集。它从 GC Root sun.awt.AppContext 保持打开状态。

我们如何清理它?或者这是我们出于某种原因不必担心的事情?我们希望努力确保我们的应用程序能够自行清理,但我们也不想在这方面旋转我们的车轮。

AppContext.mainAppContext 包含一个 HashMap,其中包含一个 BasicPopupMenuUI.MenuKeyboardHelper 实例。这里面是一个ComponentInputMapUIResource.menuInputMap,它有这个JMenuBar作为一个组件。

【问题讨论】:

    标签: java swing memory-management


    【解决方案1】:

    正如here 所讨论的,在JVM 的正常运行过程中必须明确释放许多系统资源。图形上下文的dispose() 方法就是一个例子;父窗口的dispose() 方法是另一个。在任何一种情况下,资源都可能被正确释放,但您可以在堆完成之前观察它。

    很难概括什么可以安全地忽略,但一种经验方法是在探查器中练习目标。这个comparison 中的前两个图表显示了某种疑似保留资源的方法消耗的内存小幅但稳定增加。相比之下,第三个图表显示了内存使用量与垃圾收集活动的周期性高峰。下面是视觉上“忙碌”的程序的典型锯齿模式,例如 game。请注意,每个循环都会返回基线。

    【讨论】:

    • 我添加了对JFrame.dispose() 的显式调用,但仍然得到相同的结果。在这一点上我唯一能想到的是这些资源真的不会占用很多内存,所以我不应该担心它们。清除我们加载的数百兆字节的数据比这些东西更重要,一旦某个缓冲区达到最大值或类似情况,这些数据可能会在以后被清除。
    • FileSystemView.getFileSystemView() 证明是正确的,在实践中很少被调用。我会说你专注于数据是对的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-23
    • 1970-01-01
    • 1970-01-01
    • 2016-09-01
    • 1970-01-01
    • 2021-02-16
    相关资源
    最近更新 更多