Подтвердить что ты не робот

Вызовы System.gc() с помощью основных API-интерфейсов

Некоторые из вас, вероятно, знают, что некоторые из основных API-интерфейсов Java предоставляют явные вызовы System.gc(). Я знаю два случая, когда это происходит:

  • NIO. Я считаю, что это делается для того, чтобы сделать некоторую очистку для прямых ByteBuffers, когда в системе заканчивается "прямая" память.
  • RMI. Здесь причина не для меня понятна...

Итак, вопросы:

  • Знаете ли вы, почему System.gc() требуется для RMI?
  • Знаете ли вы какие-либо другие ситуации, когда основные API (или даже некоторые другие популярные библиотеки) могут напрямую обращаться к System.gc()?
4b9b3361

Ответ 1

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

Вы можете избежать прямого ByteBuffer, нуждающегося в GC, чтобы очистить их в JVM Sun/Oracle, вызвав

ByteBuffer bb = ByteBuffer.allocateDirect(SIZE);
((DirectBuffer) bb).cleaner().clean();

Ответ 2

Я не понимаю, почему они даже разоблачили метод gc(). Даже в документации Java довольно ясно говорит о том, что поведение непредсказуемо. Док говорит

"Вызов метода gc предполагает, что виртуальная машина Java тратит усилия на повторное использование неиспользуемых объектов"

Смысл, он может делать любое количество вещей, в том числе ничего.

Что касается вопроса, многие серверы приложений называют System.gc() здесь и там. WebSphere является главным преступником, и вы можете найти его по всей базе данных WAS/Portal. Я не видел его в библиотеках/фреймворках с открытым исходным кодом, которые я помню. Возможно, люди, которые прилагают усилия для внесения вклада в эти рамки, имеют достаточный смысл не использовать операции с неопределимым поведением.

Моя догадка заключается в том, что она вызывается в моменты, когда разработчик считал, что "эта операция может при определенных обстоятельствах использовать много" временной "(недолговечной) памяти при обработке, поэтому я сделаю некоторую сборку мусора чтобы вернуть его". Вероятно, это относится и к вашему сценарию RMI. По-моему, это фиктивный. В некоторых случаях вызов System.gc() может снизить производительность, вызвав прежде всего полные циклы GC (и без необходимости). Точка, сборщик мусора довольно умный, и, если вы не уверены, что знаете лучше, не пытайтесь с этим покончить.

Ответ 3

Реализация JDK точно знает, как ведет себя ее собственный System.gc(). JDK не должен притворяться агностиком, ограничиваясь стандартным абстрактным поведением, а не конкретным проприетарным поведением (которое, конечно же, соответствует стандартным поведением)

Да, он может вызвать System.gc() по своему усмотрению. Мы не должны.

Ответ 4

Таким образом, поиска строки кода вашего приложения System.gc() недостаточно, чтобы определить, выполняет ли ваше приложение вызовы System.gc(). Таким образом, возникает проблема: как определить, выполняются ли вызовы System.gc() во всем вашем стеке приложений?

Это где GC журналы пригодятся. Включите журналы GC в своем приложении. На самом деле, рекомендуется постоянно поддерживать журнал GC на всех ваших производственных серверах, поскольку это помогает вам устранять неполадки и оптимизировать производительность приложений. Включение журналов GC добавляет незначительные (если вообще наблюдаемые) накладные расходы. Теперь загрузите ваш журнал GC в инструмент анализа журналов сбора мусора, такой как GCeasy, HP JMeter,…. Эти инструменты создают подробный отчет об анализе сбора мусора.

Подробнее читайте здесь...