System.gc () вызывает основные API - PullRequest
12 голосов
/ 04 августа 2011

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

  1. NIO. Я считаю, что это делается для того, чтобы выполнить некоторую очистку для прямых байтовых буферов, когда системе не хватает «прямой» памяти.
  2. RMI. Здесь причина не совсем понятна для меня ...

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

  1. Знаете ли вы причину, по которой System.gc () требуется для RMI?
  2. Известны ли вам какие-либо другие ситуации, когда основные API (или даже некоторые другие популярные библиотеки) могут напрямую вызывать System.gc ()?

Ответы [ 3 ]

5 голосов
/ 04 августа 2011

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

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

ByteBuffer bb = ByteBuffer.allocateDirect(SIZE);
((DirectBuffer) bb).cleaner().clean();
2 голосов
/ 04 августа 2011

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

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

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

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

Я предполагаю, что он вызывается иногда, когда разработчик чувствовал, что «эта операция может, при некоторых обстоятельствах, использовать много« временной »(недолгой) памяти при обработке, поэтому я сделаю некоторую сборку мусора чтобы вернуть его ". Это, вероятно, относится и к вашему сценарию RMI. На мой взгляд, это подделка. В некоторых случаях вызов System.gc () может снизить производительность путем преждевременного (и неоправданного) запуска полных циклов GC. Суть в том, что сборщик мусора довольно умен, и, если вы не уверены, что знаете лучше, не пытайтесь с ним связываться.

1 голос
/ 04 августа 2011

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

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

...