Как повысить приоритет FinalizerThread для сбора объектов в GC - PullRequest
5 голосов
/ 11 ноября 2011

У меня есть монитор моего приложения Java с профилировщиком, чтобы узнать утечку памяти. И я получил класс, который занимает почти 80% памяти, что

java.lang.ref.Finalizer

Тогда я гуглю это для класса выше и нашел отличную статью http://www.fasterj.com/articles/finalizer1.shtml

Теперь кто-нибудь может мне подсказать, как повысить приоритет FinalizerThread для сбора этих объектов в GC.

Еще одна проблема, с которой я сталкиваюсь в Linux с версией ядра Linux 2.6.9-5.ELsmp (i386) и Linux 2.6.18-194.17.4.el5 (i386) но работает нормально (без ошибки OOM) в Linux 2.6.18-128.el5PAE (i386).

Это проблема из-за ядер Linux? Есть ли переменная JVM для улучшения приоритета FinalizerThread?

Спасибо заранее.

Ответы [ 3 ]

2 голосов
/ 11 ноября 2011

Чтобы ответить на вопрос буквально, вы можете сделать это.Однако, как указано ниже, это, вероятно, будет бессмысленно, особенно если поток уже имеет высокий приоритет.

for(Thread t: Thread.getAllStackTraces().keySet())
    if (t.getName().equals("Finalizer")) {
        System.out.println(t);
        t.setPriority(Thread.MAX_PRIORITY);
        System.out.println(t);
    }

печатает

Thread[Finalizer,8,system]
Thread[Finalizer,10,system]

Если вы не используете 100%для всех ваших ядер или близких к ним приоритет не имеет значения, потому что даже самый низкий приоритет получит столько ЦП, сколько ему нужно.

Примечание. В Linux он будет игнорировать повышенные приоритеты, если вы не являетесь пользователем root.

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

Короче, вы должны попытаться определить, какие ресурсы завершаются, и убедиться, что им не нужно ничего делать, когда вызывается finalize (), в идеале don 'Этот метод вообще не используется.

Возможно, ресурсы закрываются на более старой версии ядра Linux немного дольше.Я бы проверил, что оборудование идентично, так как это может означать, что очистка ресурса занимает больше времени.(Но реальное исправление состоит в том, чтобы гарантировать, что это не должно делать это)

2 голосов
/ 11 ноября 2011

Поток финализатора редко должен выполнять много работы.Ресурсы уже должны были быть освобождены.Убедитесь, что ваш код обрабатывает ресурсы стандартным способом.

Java SE 7:

try (final Resource resource = acquire()) {
    use(resource);
}

Pre-Java SE 7:

final Resource resource = acquire();
try {
    use(resource);
} finally {
    resource.release();
}
0 голосов
/ 11 ноября 2011

Как отмечает Том Хотин, вы можете получить доступ к FinalizerThread, создав метод finalize(), который вызывает Thread.currentThread(), а затем сохраняет его в статическом виде. Возможно, вы также можете изменить его приоритет.

Но есть большая вероятность, что это не принесет пользы. Вероятно, будет только один поток финализатора. И проблема, вероятно, будет либо в том, что:

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

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

Но в любом случае, я думаю, что лучшее решение - это избавиться от finalize() методов. Могу поспорить, что они делают что-то ненужное ... или хитрое. В частности, использование финализаторов для извлечения ресурсов из отброшенных объектов - плохой способ решения этой конкретной проблемы. (См. Ответ Тома Хоутина.)

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