Почему JVM не может обеспечить сборку мусора - PullRequest
0 голосов
/ 10 июня 2018

Это не дубликат, поскольку тема, упомянутая как дубликат, говорит только о том, почему не следует использовать System.gc (), хотя я знаю, что это не мой вопрос.

Использование System.gc () или Runtime.getRuntime (). Gc () не всегда выполняет сборку мусора, он просто запрашивает ее и может даже игнорироваться JVM.

Есть ли причина этого?Это "случайно"?Так как я не думаю, что случайное, даже существует в программировании, мне любопытно, почему оно иногда не собирает его, а иногда и в разное время.

1 Ответ

0 голосов
/ 10 июня 2018

Да.Есть очень веская причина.


Для начала вам нужно понять несколько фактов о сборке мусора в целом:

  1. Запуск сборщика мусора стоит дорого.
  2. Запуск сборщика мусора (многократно) в неподходящее время может быть катастрофически неэффективным 1 .
  3. Почти невозможно для типичного приложения предсказать, когда можно запустить GC наиболее эффективно .

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

Использование System.gc () или Runtime.getRuntime (). gc () won 't всегда выполняет сборку мусора, он просто запрашивает его и может даже игнорироваться JVM.Есть ли причина этого?

Да. в первую очередь для защиты от катастрофических поведенческих эффектов, которые наивные программисты могут вызвать, вызвав gc() в неподходящее время.

Это "случайно""?

Нет.Это не имеет ничего общего со случайностью.

На практике типичные JVM имеют переключатель командной строки, который определяет, игнорируются ли вызовы gc() или нет.Это позволяет пользователю / развертывателю / интегратору / кому бы то ни было смягчить неправильный выбор, сделанный программистом.

Но учтите, что он не может быть переопределен из кода Java.Это побеждало бы цель сделать это переключателем командной строки.

Мне любопытно, почему он иногда не собирает его, а иногда делает, а также в разное время.

Обычное поведение JVM - попытаться запустить сборщик мусора , когда это наиболее эффективно сделать .JVM может оптимизировать двумя способами:

  • Он может оптимизировать, чтобы максимизировать пропускную способность коллекторов;то есть, чтобы минимизировать время, затрачиваемое процессором на сбор данных

  • Он может быть оптимизирован для минимизации длительности пауз ГХ;то есть время, когда JVM должна заморозить все потоки приложений во время сбора.

Это сложно.С точки зрения внешнего наблюдателя (который / который не имеет доступа к статистике кучи и т. Д.) Может быть трудно понять, почему GC работает в данный момент времени.Но это, конечно, не случайное .


1 - Одно из противоречивых свойств алгоритма ГХ заключается в том, что стоимость сбора (в большинстве случаев) является доминирующейзатратами на отслеживание объектов без мусора и перемещение в памяти для объединения свободного пространства.Поэтому, если вы позвоните в GC, когда не будет большого количества мусора, который вы собираетесь собрать, вы в конечном итоге будете отслеживать / перемещать большое количество не-мусора за небольшую реальную выгоду.Напротив, у JVM есть лучшее понимание того, когда самое подходящее время для сбора.Для начала он знает, сколько места осталось в каждом пуле в любой момент времени.

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

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