Я знаю, что сборка мусора в Java автоматизирована. Но я понял, что если вы вызовете System.gc()
свой код, JVM может решить или не решить выполнить сборку мусора в этот момент. Как именно это работает? На каком основании / параметрах именно JVM решает делать (или не делать) сборщик мусора, когда видит System.gc()
?
Есть ли какие-нибудь примеры, и в таком случае было бы неплохо поместить это в свой код?
java
garbage-collection
Майкл
источник
источник
Ответы:
На практике обычно решает сделать сборку мусора. Ответ зависит от множества факторов, например от того, на какой JVM вы работаете, в каком режиме она работает и какой алгоритм сборки мусора использует.
Я бы не стал полагаться на это в вашем коде. Если JVM собирается выбросить OutOfMemoryError, вызов System.gc () не остановит его, потому что сборщик мусора попытается освободить столько, сколько сможет, прежде чем он дойдет до этой крайности. Единственный раз, когда я видел его на практике, - это в IDE, где он прикреплен к кнопке, которую пользователь может нажать, но даже там это не очень полезно.
источник
System.gc()
на экране загрузки видеоигры. В тот момент мне было бы все равно, очистил ли вызов все, что он мог, или вообще ничего не сделал. Однако я бы предпочел, чтобы он «тратил усилия на переработку неиспользуемых объектов» во время экрана загрузки, а не во время игры.Единственный пример, который я могу придумать, когда имеет смысл вызывать System.gc (), - это профилирование приложения для поиска возможных утечек памяти. Я считаю, что профилировщики вызывают этот метод непосредственно перед тем, как сделать снимок памяти.
источник
Спецификация языка Java не гарантирует, что JVM запустит сборщик мусора при вызове
System.gc()
. Это причина того, что «может или не может решить сделать сборку мусора на этом этапе».Теперь, если вы посмотрите исходный код OpenJDK , который является основой Oracle JVM, вы увидите, что вызов
System.gc()
действительно запускает цикл GC. Если вы используете другую JVM, такую как J9, вам нужно проверить их документацию, чтобы узнать ответ. Например, JVM Azul имеет сборщик мусора, который работает постоянно, поэтому вызовSystem.gc()
ничего не сделает.В другом ответе упоминается запуск GC в JConsole или VisualVM. По сути, эти инструменты делают удаленный вызов
System.gc()
.Обычно вы не хотите запускать цикл сборки мусора из вашего кода, так как это портит семантику вашего приложения. Ваше приложение выполняет некоторые бизнес-задачи, а JVM заботится об управлении памятью. Вы должны разделить эти проблемы (не заставляйте свое приложение управлять памятью, сосредоточьтесь на бизнесе).
Однако есть несколько случаев, когда призыв
System.gc()
может быть понятным. Рассмотрим, например, микротест. Никто не хочет, чтобы цикл GC происходил в середине микробенчмарка. Таким образом, вы можете запускать цикл ГХ между каждым измерением, чтобы каждое измерение начиналось с пустой кучи.источник
У вас нет контроля над сборщиком мусора в java - решает виртуальная машина. Я ни разу не встречал случая, когда
System.gc()
это необходимо . ПосколькуSystem.gc()
вызов просто ПРЕДЛАГАЕТ, что виртуальная машина выполняет сборку мусора, а также выполняет ПОЛНУЮ сборку мусора (старые и новые поколения в куче нескольких поколений), он может фактически вызвать БОЛЬШЕ циклов процессора, чем необходимо.В некоторых случаях может иметь смысл предложить виртуальной машине выполнить полную сборку СЕЙЧАС, поскольку вы можете знать, что приложение будет бездействовать в течение следующих нескольких минут, прежде чем произойдет тяжелая работа. Например, сразу после инициализации большого количества временных объектов во время запуска приложения (т. Е. Я только что кэшировал ТОННУ информации и знаю, что в течение минуты или около того у меня не будет большой активности). Подумайте о запуске IDE, например о запуске eclipse - он многое делает для инициализации, поэтому, возможно, сразу после инициализации имеет смысл выполнить полный gc на этом этапе.
источник
При звонке нужно быть очень осторожным
System.gc()
. Его вызов может добавить ненужные проблемы с производительностью в ваше приложение, и не гарантируется фактическое выполнение сбора. Фактически можно отключить явноеSystem.gc()
использование аргумента java-XX:+DisableExplicitGC
.Я настоятельно рекомендую прочитать документы, доступные на Java HotSpot Garbage Collection, чтобы получить более подробные сведения о сборке мусора.
источник
System.gc()
реализуется виртуальной машиной, и то, что она делает, зависит от реализации. Разработчик может, например, просто вернуться и ничего не делать.Что касается того, когда запускать сбор вручную, единственный раз, когда вы можете захотеть это сделать, - это когда вы отказываетесь от большой коллекции, содержащей множество меньших коллекций -
Map<String,<LinkedList>>
например, - и вы хотите попробовать и тогда выполнить хит, и есть, но по большей части вам не стоит об этом беспокоиться. К сожалению, GC знает лучше вас большую часть времени.источник
Если вы используете прямые буферы памяти, JVM не запускает GC за вас, даже если у вас мало прямой памяти.
Если вы звоните
ByteBuffer.allocateDirect()
и получаете OutOfMemoryError, вы можете обнаружить, что этот вызов в порядке после запуска GC вручную.источник
Cleaners
которого используется прямая память. то есть он не освобождается потоком финализатора, так как это может быть слишком медленным. Тем не менее, можно получить OOME, если вы особенно быстро создаете области прямой памяти. Решение состоит в том, чтобы не делать этого и повторно использовать области прямой памяти там, где это возможно.Большинство JVM запускают сборщик мусора (в зависимости от переключателей -XX: DiableExplicitGC и -XX: + ExplicitGCInvokesConcurrent). Но спецификация просто менее четко определена, чтобы позволить более эффективную реализацию позже.
Спецификация нуждается в пояснении: Ошибка № 6668279: (spec) System.gc () должна указывать на то, что мы не рекомендуем использовать и не гарантируем поведение
Внутренне метод gc используется RMI и NIO, и они требуют синхронного выполнения, что: в настоящее время обсуждается:
Ошибка № 5025281: Разрешить System.gc () запускать одновременные (не останавливающие мир) полные коллекции
источник
Garbage Collection
хорошоJava
, если мы выполняем программное обеспечение, закодированное на java, на рабочем столе / ноутбуке / сервере. Вы можете позвонитьSystem.gc()
илиRuntime.getRuntime().gc()
войтиJava
.Просто обратите внимание, что ни один из этих вызовов не даст никаких гарантий. Это просто предложение для jvm запустить сборщик мусора. Это зависит от JVM, независимо от того, запускает ли она GC или нет. Итак, короткий ответ: мы не знаем, когда он запустится. Более длинный ответ: JVM запустит gc, если для этого будет время.
Думаю, то же самое и с Android. Однако это может замедлить работу вашей системы.
источник
Обычно виртуальная машина выполняет сборку мусора автоматически перед выдачей исключения OutOfMemoryException, поэтому добавление явного вызова не должно помочь, за исключением того, что оно, возможно, перемещает снижение производительности на более ранний момент времени.
Однако, думаю, я столкнулся со случаем, когда это могло быть актуально. Я не уверен, так как мне еще предстоит проверить, имеет ли это какой-либо эффект:
Когда вы сопоставляете файл с памятью, я считаю, что вызов map () вызывает исключение IOException, когда достаточно большой блок памяти недоступен. Я думаю, что сборка мусора непосредственно перед файлом map () может помочь предотвратить это. Что вы думаете?
источник
мы никогда не сможем заставить сборку мусора. System.gc предлагает только vm для сборки мусора, однако на самом деле, в какое время механизм запускается, никто не знает, это как указано в спецификациях JSR.
источник
Следует ОЧЕНЬ много сказать о том, чтобы потратить время на проверку различных настроек сборки мусора, но, как было упомянуто выше, обычно это бесполезно.
В настоящее время я работаю над проектом, включающим среду с ограниченной памятью и относительно большие объемы данных - есть несколько больших фрагментов данных, которые доводят мою среду до предела, и хотя я смог снизить использование памяти, поэтому что теоретически он должен работать нормально, я все равно буду получать ошибки пространства кучи - подробные параметры GC показали мне, что он пытался собрать мусор, но безрезультатно. В отладчике я мог бы выполнить System.gc () и, конечно же, было бы «много» доступной памяти ... не много лишней, но достаточно.
Следовательно, единственное время, когда мое приложение вызывает System.gc (), - это когда оно собирается войти в сегмент кода, где будут выделены большие буферы, необходимые для обработки данных, и проверка доступной свободной памяти показывает, что я не гарантированно иметь это. В частности, я смотрю на среду размером 1 ГБ, где не менее 300 МБ занято статическими данными, при этом основная часть нестатических данных связана с выполнением, за исключением случаев, когда обрабатываемые данные составляют не менее 100-200 МБ при источник. Все это часть процесса автоматического преобразования данных, поэтому все данные существуют в течение относительно коротких периодов времени в долгосрочной перспективе.
К сожалению, хотя информация о различных параметрах настройки сборщика мусора доступна, это в основном экспериментальный процесс, и детали более низкого уровня, необходимые для понимания того, как обрабатывать эти конкретные ситуации, получить нелегко.
При этом, несмотря на то, что я использую System.gc (), я продолжал настраивать параметры командной строки и смог значительно улучшить общее время обработки моего приложения, несмотря на то, что не смог преодолеть Камень преткновения возникает при работе с большими блоками данных. При этом System.gc () - это инструмент ... очень ненадежный инструмент, и если вы не будете осторожны с тем, как вы его используете, вы захотите, чтобы он не работал чаще, чем нет.
источник
Если вы хотите знать,
System.gc()
вызывается ли ваш , вы можете с новым обновлением Java 7 4 получать уведомление, когда JVM выполняет сборку мусора.Я не на 100% уверен, что класс GarbageCollectorMXBean был представлен в Java 7 update 4, хотя я не мог найти его в примечаниях к выпуску, но я нашел информацию на сайте javaperformancetuning .com
источник
Я не могу вспомнить конкретный пример, когда можно использовать явный сборщик мусора.
В общем, выполнение явного сборщика мусора может на самом деле принести больше вреда, чем пользы, потому что явный сборщик мусора вызовет полную коллекцию, которая занимает значительно больше времени при прохождении через каждый объект. Если этот явный сборщик мусора будет вызывать неоднократно, это может легко привести к замедлению работы приложения, поскольку много времени уходит на запуск полных сборщиков мусора.
В качестве альтернативы, если вы перебираете кучу с анализатором кучи и вы подозреваете, что компонент библиотеки вызывает явный сборщик мусора, вы можете отключить его, добавив: gc = -XX: + DisableExplicitGC к параметрам JVM.
источник
Согласно «Мышлению на Java» Брюса Экеля, один из вариантов использования явного вызова System.gc () - это когда вы хотите принудительно завершить завершение, то есть вызов метода финализации .
источник
пока работает system.gc, он остановит мир: все респоны остановлены, поэтому сборщик мусора может сканировать каждый объект, чтобы проверить, нужно ли его удалить. если приложение является веб-проектом, все запросы останавливаются до завершения gc, и это приведет к тому, что ваш веб-проект не сможет работать в одночасье.
источник