Можете ли вы рассчитывать на вызов .finalize ()? - PullRequest
8 голосов
/ 24 октября 2011

Я пытался применить часть своего Java-кода, чтобы убедиться, что объекты собирались мусором правильно, и обнаружил, что удивительно, что он вызывался не так часто, как я ожидал.

Теперь мне интересно,это из-за неисправного инструментария или фактической утечки памяти, которую я должен решить.профилировщик VisualVM, кажется, указывает на первое.

Ситуация, вызывающая обеспокоенность, заключается в том, что у меня есть поток, который обрабатывает запросы, и внутри запроса создаются тысячи временных объектов.Иногда сокет, в который пишет этот поток, неожиданно закрывается, и поток попадает в исключение и умирает.

Когда поток умирает, кажется, что .finalize () никогда не вызывается для этих объектов.Это причина не доверять моим инструментам?

Ответы [ 4 ]

4 голосов
/ 24 октября 2011

Finalize () не является решением. Вы не можете знать, когда будет вызван финализатор, если таковые имеются. Если ваша проблема - исключение, используйте блоки try/catch/finally и закройте / очистите все, что вы хотите закрыть в блоке finally. Это гарантирует, что все будет очищено в обоих случаях: логика завершилась нормально или было сгенерировано исключение.

2 голосов
/ 24 октября 2011

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

Об этом можно прочитать в финализации экземпляров класса часть языковой спецификации.

1 голос
/ 24 октября 2011

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

От java.lang.Object javadoc:

The Java programming language does not guarantee which thread will invoke the finalize method for any given object.

http://download.oracle.com/javase/1.5.0/docs/api/java/lang/Object.html#finalize()

Как я вижу, страшная финализация должна и будет использоваться только в том случае, если вы включите некоторый нативный код в свое приложение.Но даже в этом случае не полагайтесь на это.

0 голосов
/ 24 октября 2011

Ваша путаница, похоже, связана с утечкой памяти или нет. Вы пытаетесь установить это, посмотрев, был ли вызван finalize() или нет. Если это так, то неправильно проверять, есть ли утечка памяти или нет.

Для ясности, в Java утечки памяти в основном означают скрытые ссылки на ненужные вам объекты.

Цель finalize() предоставить разработчику возможность убирать собственный беспорядок (соединения, потоки, ...). Предполагается, что память - это беспорядок / головная боль в JVM и очищена GC.

Короче говоря, тот факт, что " GC гарантирует вызов finalize() до освобождения памяти ", не должен интерпретироваться как ", если finalize() не вызывается, есть память утечка ». Возможно, этот объект не является и все же сборщиком мусора.

Если вы ищете утечку памяти, используйте инструмент. Смотри варианты:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...