9

Одним из утечек памяти, которые я обнаружил в нашем приложении, является приватное статическое поле java.awt.Window.allWindows, которое отслеживает каждое созданное окно. У нас есть диалоговые окна, которые создаются, используются, а затем забываются, и ожидалось, что они исчезнут и будут собраны мусор. Это частное поле сохраняет их неограниченно, до тех пор, пока на них не будет вызван метод dispose(). И по определению мы не можем этого сделать, когда они вышли из сферы действия.Зачем вам нужно распоряжаться() java.awt.Window, выходящим за рамки?

Я не понимаю, почему это спроектировано таким образом. Кажется противоречащим духу сборки мусора, чтобы явным образом позволял системе знать, когда я закончил объект Window. Очевидно, я покончил с этим, так как он выходит за рамки.

Я понимаю, что делает метод dispose(): избавление от системных одноранговых объектов. Я понимаю, что это вне Java и что вам нужно какой-то способ сделать это, и что Swing не должен просто потерять контроль над этими объектами, иначе он будет иметь утечку памяти. Но что делается, сохраняя ссылку на мое Окно навсегда, когда я никогда не буду использовать его снова?

Может кто-нибудь объяснить, почему это необходимо?

+0

Когда вызывается 'removeNotify',' Window' будет удален из 'allWindows'. 'Window' содержат собственные ресурсы и поэтому должны быть удалены так же, как если бы это было соединение с базой данных. –

+0

У меня создалось впечатление, что когда мои подключения к базе данных выходят из сферы действия, они автоматически закрываются.Возможно, я ошибаюсь. :) В настоящее время, хотя, все это для меня управляет сервером, за исключением коротких программ. – skiphoppy

ответ

14

Ненавижу говорить об этом, но это именно то, как работает графический интерфейс.

Windows неблокируются. Это означает, что после создания кода в коде код продолжает выполняться.

Это означает, что ваше окно, вероятно, выходит из сферы действия сразу после создания, если вы явно не сохранили ссылку на него где-то в другом месте. Окно по-прежнему находится на экране в этот момент.

Это также означает, что вам нужен другой способ избавиться от него, когда вы закончите с ним. Введите метод Window dispose(), который можно вызвать из одного из слушателей окна.

+1

D'oh! Я понял! Люди постоянно создают окна, на которые они не ссылаются, но окна все еще видны и работают. Я просто не думал об этом, потому что в этой ситуации мы сразу же используем окно, а затем делаем его невидимым, а затем забываем о нем (выходит за рамки). Теперь я вижу, почему это значение по умолчанию для окон. Я знал, что где-то есть рациональный вариант использования. :) – skiphoppy

+0

О, хорошо, я должен был указать, что окно все еще было на экране, когда его переменная вышла из сферы действия. Я отредактирую это в своем ответе на всякий случай, если кто-то пропустит это. – Powerlord

2

Это может объяснить: AWT Threading Issues

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

Я согласен, что это немного мудак. Я несколько раз сталкивался с этим несколько раз.

1

В Java, когда у вас есть собственный код (который является тем, что представляют собой эти компоненты Windows), вам нужно сохранить ссылку, чтобы предотвратить сборщик мусора от сбора мусора, собирающего объект, в то время как внутренние указатели все еще вокруг, что вызовет всевозможные плохие вещи (аварии VM и т. д.).

См., Например, обсуждение here.

1

Метод dispose() уничтожает объект, находящийся в объекте WindowEvent. Он не убивает приложение/p