Как мне получить AppContext для выпуска компонентов AWT, чтобы они могли собирать мусор?

Моя команда работает над анализом нашего приложения Swing, чтобы убедиться, что все мусор собран, когда он больше не используется. Мы сталкиваемся с нечетной проблемой.

Мы просто открываем новое окно (JFrame) и закрываем его. Этот кадр содержит класс EmptyPanel (который содержит короткое сообщение о отсутствии данных) и пользовательский класс JMeunBar. Мы вообще не взаимодействуем с этим - сразу закройте окно.

Затем мы вынуждаем сборку мусора и делаем кучу кучи.

При анализе дампа кучи JMenuBar не собирается мусор. Он остается открытым от GC Root sun.awt.AppContext.

Как мы это очищаем? Или это то, о чем нам не нужно беспокоиться по какой-то причине? Мы хотим быть прилежными, чтобы убедиться, что наше приложение очистится после себя, но мы также не хотим вращать наши колеса.

AppContext.mainAppContext содержит HashMap, который содержит экземпляр BasicPopupMenuUI.MenuKeyboardHelper. Внутри это ComponentInputMapUIResource.menuInputMap, который имеет этот JMenuBar как компонент.

Ответ 1

Как обсуждалось здесь, существует ряд системных ресурсов, которые должны быть явно освобождены в ходе обычной работы JVM. Одним из примеров является графический контекст dispose(); родительское окно dispose() - другое. В любом случае ресурс может быть правильно выпущен, но вы можете наблюдать кучу до того, как она будет завершена.

Трудно обобщить то, что можно смело игнорировать, но один эмпирический подход - использовать цель в профилировщике. Первые два графика в этом сравнении показывают небольшое, но неуклонное увеличение объема памяти, потребляемого определенным методом, который, как предполагается, удерживает ресурсы. Напротив, третий график показывает использование плоской памяти с периодическими всплесками деятельности по сбору мусора. Ниже приведен типичный образ пиломатериала визуально "занятой" программы, такой как игра. Обратите внимание, что каждый цикл возвращается к базовой линии.

enter image description here