Можем ли мы отключить финализаторы?

Поскольку существует небольшая гарантия того, когда и даже если финализаторы запускаются, а финализаторы в настоящее время считаются запахом, - есть ли способ убедить JVM полностью пропустить все процессы финализации?

Я прошу, потому что у нас есть приложение с мамонтом, которое при переходе на новую JVM (не уверен, что на этом этапе) оказывается на коленях тем, что очень похоже на известные проблемы с финализаторами (исключение выбрано и, следовательно, очень медленный GC).

Добавлен

Существует некоторая дискуссия по Устранение проблемы утечки Java-памяти: финализация?, где предполагается, что основная проблема возникает, когда исключения исключаются из финализаторов, поскольку это замедляет процесс окончательной доработки.

Моя проблема проявляется в резком замедлении, когда память становится низкой, а анализ дампов кучи показывает большое количество объектов Finalizer (более 10 000 000), что указывает на то, что замедление может быть их ошибкой, поскольку они задерживают GC. Очевидно, я ошибаюсь.

У меня нет возможности требовать рефакторинга.

Ответы

Ответ 1

Есть ли способ убедить JVM полностью пропустить все процессы финализации?

Словом Нет.

Но если большая часть ваших объектов имеет методы finalize и/или методы finalize, особенно дороги, я думаю, что они вряд ли сделают GC "очень медленным". Я ожидаю, что проблема в другом.

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

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


ОБНОВЛЕНИЕ - ваши новые доказательства довольно убедительные, хотя и не доказательство!.

У меня нет возможности требовать рефакторинга.

Затем я предлагаю вам поставить доказательства у ног людей, которые делают: -).

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

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

Ответ 2

Это , чтобы подавить финализацию на определенных объектах. Он не требует обработки байт-кода, как заметил один комментатор.

Процедура описана здесь и предоставляется исходный код. Класс java.lang.ref.Finalizer отвечает за ведение списка объектов, которые еще не были доработаны. Чтобы подавить завершение ваших интересующих объектов, достаточно использовать API-интерфейсы отражения, чтобы получить блокировку в поле lock, перебрать связанный список unfinalized, который поддерживает класс Finalizer, и удалить ваш объект из этого списка.

Я пробовал этот метод для безопасного создания пользовательских сериализованных объектов, минуя вызов конструктора и избегая проблем, когда финализатор будет вызываться с обычным GC. Перед применением этого метода моя JVM будет ломаться с жесткими ошибками в потоке финализатора; поскольку применение этого метода не происходит.

Ответ 3

Вы не можете отключить finalizer в java, но все, что вы можете сделать, это написать код, который облегчит GC: -).