Вопрос-ответ

When does System.gc() do something?

Когда System.gc() что-то делает?

Я знаю, что сборка мусора в Java автоматизирована. Но я понял, что если вы вызываете System.gc() в своем коде, JVM может решить, выполнять сборку мусора в этот момент, а может и нет. Как именно это работает? На основе каких именно параметров JVM решает выполнять (или не выполнять) GC, когда видит System.gc()?

Есть ли какие-нибудь примеры, в которых было бы хорошей идеей включить это в свой код?

Переведено автоматически
Ответ 1

На практике он обычно решает выполнить сборку мусора. Ответ зависит от множества факторов, например, от того, на какой JVM вы работаете, в каком режиме она находится и какой алгоритм сборки мусора она использует.

Я бы не стал зависеть от этого в вашем коде. Если JVM собирается выдать OutOfMemoryError, вызов System.gc() это не остановит, потому что сборщик мусора попытается освободить столько, сколько сможет, прежде чем дойдет до такой крайности. Единственный раз, когда я видел, как это используется на практике, - это в IDE, где оно прикреплено к кнопке, которую пользователь может нажать, но даже там это не очень полезно.

Ответ 2

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

Ответ 3

У вас нет контроля над GC в java - решает виртуальная машина. Я никогда не сталкивался со случаем, когда System.gc() это необходимо. Поскольку System.gc() вызов просто ПРЕДПОЛАГАЕТ, что виртуальная машина выполняет сборку мусора, а также выполняет ПОЛНУЮ сборку мусора (старое и новое поколения в многопоколенной куче), то на самом деле это может привести к тому, что будет потреблено БОЛЬШЕ циклов процессора, чем необходимо.

В некоторых случаях может иметь смысл предложить виртуальной машине выполнить полный сбор данных СЕЙЧАС, поскольку вы, возможно, знаете, что приложение будет простаивать в течение следующих нескольких минут, прежде чем начнется тяжелая работа. Например, сразу после инициализации большого количества временных объектов во время запуска приложения (т. Е. Я только что кэшировал ТОННУ информации, и я знаю, что не получу большой активности в течение минуты или около того). Подумайте о запуске IDE, такой как eclipse - она многое делает для инициализации, поэтому, возможно, сразу после инициализации имеет смысл выполнить полный gc в этот момент.

Ответ 4

Спецификация языка Java не гарантирует, что JVM запустит GC при вашем вызове System.gc(). Это причина того, что "может или не может решить выполнить GC в этот момент".

Теперь, если вы посмотрите на исходный код OpenJDK, который является основой Oracle JVM, вы увидите, что вызов System.gc() действительно запускает цикл GC. Если вы используете другую JVM, такую как J9, вам нужно проверить их документацию, чтобы узнать ответ. Например, в JVM Azul есть сборщик мусора, который работает непрерывно, поэтому вызов System.gc() ничего не сделает

В некоторых других ответах упоминается запуск GC в JConsole или VisualVM. По сути, эти инструменты выполняют удаленный вызов System.gc().

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

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

2023-06-26 06:58 java