Что такое сборщик мусора в Java?


104

Я новичок в Java и смущен сборщиком мусора в Java. Что он на самом деле делает и когда начинает действовать. Опишите, пожалуйста, некоторые свойства сборщика мусора в Java.


2
возможный дубликат сборщика мусора
Ян Рингроуз

10
Иногда лучше прочитать главу в хорошей книге, рассчитывая понять сложный предмет, ответив на один вопрос.
Ян Рингроуз,

4
@Ian Это похожий вопрос, но не дубликат. И этот вопрос пахнет домашней работой.
NullUserException

Ответы:


119

Сборщик мусора это программа , которая работает на Java Virtual Machine , которая избавляется от объектов , которые не используются приложением Java больше. Это форма автоматического управления памятью .

Когда типичное приложение Java работает, оно создает новые объекты, такие как Strings и Files, но через определенное время эти объекты больше не используются. Например, взгляните на следующий код:

for (File f : files) {
    String s = f.getName();
}

В приведенном выше коде String sсоздается на каждой итерации forцикла. Это означает, что на каждой итерации для создания Stringобъекта выделяется немного памяти .

Возвращаясь к коду, мы видим, что после выполнения одной итерации на следующей итерации Stringобъект, созданный на предыдущей итерации, больше не используется - этот объект теперь считается «мусором».

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

Вот здесь и вступает в дело сборщик мусора.

Сборщик мусора будет искать объекты, которые больше не используются, и избавляется от них, освобождая память, чтобы другие новые объекты могли использовать эту часть памяти.

В Java управление памятью осуществляется сборщиком мусора, но в других языках, таких как C, необходимо выполнять управление памятью самостоятельно, используя такие функции, как mallocиfree . Управление памятью - одна из тех вещей, в которых легко сделать ошибки, что может привести к так называемым утечкам памяти - местам, где память не восстанавливается, когда она больше не используется.

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


Можно ли сказать, что Java-приложение, работающее на компьютере, имеет две функции сборки мусора. Один с виртуальной машиной Java. А затем еще один на реальной машине, на которой работает Windows? (Или любая другая ОС)
Lealo

Нет, обычно приложения Java запускаются только при наличии JRE. Итак, требуется только функция сборки мусора JVM! @Lealo
Am_I_Helpful

18

Он освобождает память, выделенную для объектов, которые больше не используются программой - отсюда и название «мусор». Например:

public static Object otherMethod(Object obj) {
    return new Object();
}

public static void main(String[] args) {
    Object myObj = new Object();
    myObj = otherMethod(myObj);
    // ... more code ...  
}

Я знаю, что это чрезвычайно надумано, но здесь, после того, как вы вызываете otherMethod()исходный объект Objectcreated, становится недоступным - и этот «мусор» собирается сборщиком мусора.

В Java сборщик мусора запускается автоматически, но вы также можете вызвать его явно System.gc()и попытаться принудительно запустить сборку мусора. Как указывает Паскаль Тивент, вам действительно не следует этого делать, и это может принести больше вреда, чем пользы (см. Этот вопрос ).

Для получения дополнительной информации см. Запись в википедии о сборке мусора и настройке сборки мусора (от Oracle)


1
AFAIK System.gc()не заставляет GC запускаться.
Итай Каро,

1
+1 за хороший пример кода. Обратите внимание, что сборщик мусора может уничтожить myObjдо того, как произойдет вызов otherMethod, потому myObjчто в этот момент он больше не доступен.
Билли Онил

@Italy Я считаю, что это зависит от реализации.
NullUserException

2
Я считаю, что не следует звонить System.gc(), весь смысл наличия GC в том, чтобы этого не делать.
Паскаль Тивент,

с анализом escape ( en.wikipedia.org/wiki/Escape_analysis ) возможно, что JVM может даже не выделить объект в первую очередь в этом примере. Все создание объекта может (теоретически) быть оптимизировано. Конечно, зависит от реализации.
mikera

15

Объект получает право на сборку мусора или сборщик мусора, если он недоступен из каких-либо живых потоков или статических ссылок.

Другими словами, вы можете сказать, что объект имеет право на сборку мусора, если все его ссылки равны нулю. Циклические зависимости не считаются ссылкой, поэтому, если объект A имеет ссылку на объект B, а объект B имеет ссылку на объект A и у них нет другой живой ссылки, то оба объекта A и B будут иметь право на сборку мусора.


Генерация кучи для сборки мусора -

Объекты Java создаются Heapи Heapделятся на три части или поколения для сборки мусора в Java, они называются молодым (новым) поколением, постоянным (старым) поколением и пермской областью кучи.

Пространство кучи Java Новое поколение делится на три части, известные как пространство Эдема, пространство Выжившего 1 и пространство Выжившего 2. Когда объект впервые создается в куче, он создается в новом поколении внутри пространства Eden, а после последующей незначительной сборки мусора, если объект выживает, он перемещается в выживший 1, а затем в оставшийся в живых 2 до того, как основная сборка мусора переместит этот объект в старое или постоянное поколение .

Пермское пространство Java Heap - это место, где JVM хранит метаданные о классах и методах, пуле строк и деталях уровня класса.

Генерация кучи для сборки мусора

Подробнее см. Здесь: Сборка мусора


Вы не можете заставить JVM запускать сборку мусора, хотя вы можете сделать запрос с помощью метода System.gc()или Runtime.gc().

В java.lang.System

public static void gc() {
    Runtime.getRuntime().gc();  
}

В java.lang.Runtime

public native void gc();  // note native  method

Маркировка и алгоритм развертки -

Это один из самых популярных алгоритмов, используемых сборкой мусора. Любой алгоритм сборки мусора должен выполнять 2 основные операции. Во-первых, он должен иметь возможность обнаруживать все недостижимые объекты, а во-вторых, он должен освободить пространство кучи, используемое объектами мусора, и снова сделать это пространство доступным для программы.

Вышеуказанные операции выполняются алгоритмом Mark и Sweep в два этапа:

  1. Отметить фазу
  2. Фаза развертки

подробнее читайте здесь - Алгоритм отметки и развертки


6

Сборщик мусора подразумевает, что объекты, которые больше не нужны программе, являются «мусором» и могут быть выброшены.


6

Сборщик мусора является частью JRE, который гарантирует, что объект, на который нет ссылок, будет освобожден из памяти.
Обычно он запускается, когда у вашего приложения заканчивается память. AFAIK он содержит граф, который представляет связи между объектами и изолированными объектами, которые могут быть освобождены.
Чтобы сохранить производительность, текущие объекты сгруппированы в поколения, каждый раз, когда GC сканирует объект и обнаруживает, что он все еще ссылается, его счетчик генерации увеличивается на 1 (до некоторого максимального максимального значения, 3 или 4, я думаю), и новое поколение сканируется первым (чем короче объект в памяти, тем более вероятно, что он больше не нужен), поэтому не все объекты сканируются каждый раз при запуске GC.
прочтите это для получения дополнительной информации.


@quantumSoup, ты уверен в этом? Я считаю, что какая-то сборка мусора (более дорогая) происходит только при заполнении кучи.
Пабло Фернандес

2
@quantumSoup - это зависит от реализации GC в JRE. Во многих случаях GC не работает постоянно. Вместо этого он запускается, когда ваше приложение не может выделить объект из-за переполнения кучи. Последние JVM HotSpot включают параллельный сборщик мусора, но по умолчанию он не включен.
Stephen C

В этом ответе слишком много внимания уделяется механизму. Вопрос был «Что такое сборщик мусора», а не «Как работает сборщик мусора»
Билли Онил

@quantum: нейтрализовал ваш -1, потому что: Обучение, то есть, для чего эта страница, верно? Чтобы учиться, нужно делать ошибки. Наказание за ошибки заставляет людей не учиться. Надеюсь, вы согласитесь с этим. А может, здесь вы ошиблись.
erikbwork

1
@erikb: По такой логике голосов против не было. И отрицательные голоса необходимы, чтобы отсеять относительно плохие ответы. OP, очевидно, новичок, и конкретная внутренняя работа GC просто не важна для задаваемого вопроса. Поскольку этот ответ не отвечает на заданный вопрос (он отвечает на другой), отрицательные голоса вполне оправданы.
Билли Онил

3

Сборщик мусора позволяет вашему компьютеру имитировать компьютер с бесконечной памятью. Остальное - просто механизм.

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

РЕДАКТИРОВАТЬ: Да, ссылка предназначена для C #, но C # и Java в этом отношении идентичны.


На самом деле есть вопрос о разнице между Java и C # GC: stackoverflow.com/questions/492703/c-vs-java-garbage-collector
NullUserException

3

Многие думают, что сборщик мусора собирает и удаляет мертвые объекты.
На самом деле сборка мусора Java делает наоборот! Живые объекты отслеживаются, а все остальное считается мусором.

Когда объект больше не используется, сборщик мусора освобождает базовую память и повторно использует ее для распределения объектов в будущем. Это означает, что явного удаления нет и операционная система не получает памяти. Чтобы определить, какие объекты больше не используются, JVM периодически запускает то, что очень удачно называется алгоритмом mark-and-sweep.

Проверьте это для получения более подробной информации: http://javabook.compuware.com/content/memory/how-garbage-collection-works.aspx


1

Чтобы выразить это в самых простых терминах, которые могут понять даже непрограммисты, когда программа обрабатывает данные, она создает промежуточные данные и пространство для хранения (переменные, массивы, определенные метаданные объекта и т. Д.) Для этих данных.

Когда доступ к этим объектам осуществляется через функции или превышает определенный размер, они выделяются из центральной кучи. Затем, когда они больше не нужны, их нужно очистить.

В Интернете есть несколько очень хороших статей о том, как это работает, поэтому я остановлюсь только на самом базовом определении.

GC - это в основном функция, которая выполняет эту очистку. Для этого очищаются записи таблицы, на которые не ссылаются никакие активные объекты, эффективно удаляя объекты, затем копирует и сжимает память. Это немного сложнее, но идею вы поняли.

Большая проблема заключается в том, что в некоторых частях этого процесса часто требуется временная остановка всей виртуальной машины Java, а также весь этот процесс очень интенсивно использует процессор и пропускную способность памяти. Различные варианты ГХ и параметры настройки для каждого из них предназначены для того, чтобы сбалансировать эти различные проблемы со всем процессом ГХ.


0

Сборка мусора в Java (а также на других языках / платформах) - это способ для среды выполнения java (JRE) повторно использовать память из объектов Java, которые больше не нужны. Проще говоря, при первоначальном запуске JRE запрашивает у операционной системы (O / S) определенный объем памяти. Когда JRE запускает ваше приложение (я), она использует эту память. Когда ваше приложение завершает работу с этой памятью, появляется JRE «Сборщик мусора», который освобождает эту память для использования различными частями ваших существующих приложений. «Сборщик мусора» JRE - это фоновая задача, которая всегда выполняется и пытается выбрать время, когда система простаивает, чтобы продолжить работу с мусором.

Аналогия из реального мира: мусорщики, которые приходят к вам домой и собирают ваш перерабатываемый мусор ... в конечном итоге, его повторно используют вы и / или другие люди.


0

Сборщик мусора можно рассматривать как диспетчер счетчика ссылок. если объект создан и его ссылка сохраняется в переменной, его счетчик ссылок увеличивается на единицу. в ходе выполнения, если этой переменной присвоено значение NULL. счетчик ссылок для этого объекта уменьшается. поэтому текущий счетчик ссылок для объекта равен 0. Теперь, когда сборщик мусора выполняется, он проверяет объекты с нулевым счетчиком ссылок и освобождает выделенные ему ресурсы.

Вызов сборщика мусора контролируется политиками сборки мусора.

Вы можете получить некоторые данные здесь. http://www.oracle.com/technetwork/java/gc-tuning-5-138395.html


1
Подсчет ссылок - один из плохих способов реализовать сборщик мусора. Я не думаю, что это используется в какой-либо крупной реализации JVM.
NullUserException

0

Сборщик мусора - это компонент jvm.

Он используется для сбора мусора, когда процессор освобождается.

Здесь мусор означает неиспользуемые объекты, которые он запускает в фоновом режиме основной программы.

следить за статусом основной программы.


0

Автоматическая сборка мусора - это процесс просмотра памяти кучи, определения того, какие объекты используются, а какие нет, и удаления неиспользуемых объектов. Используемый объект или объект, на который имеется ссылка, означает, что некоторая часть вашей программы все еще поддерживает указатель на этот объект. На неиспользуемый объект или объект, на который нет ссылок, больше не ссылается какая-либо часть вашей программы. Таким образом, память, используемая объектом, на который нет ссылки, может быть возвращена.

В таком языке программирования, как C, выделение и освобождение памяти выполняется вручную. В Java процесс освобождения памяти автоматически обрабатывается сборщиком мусора. Пожалуйста, проверьте ссылку для лучшего понимания. http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/gc01/index.html


0

Сборка мусора относится к процессу автоматического освобождения памяти в куче путем удаления объектов, которые больше не доступны в вашей программе. Куча - это память, которая называется свободным хранилищем и представляет собой большой пул неиспользуемой памяти, выделенной вашему Java-приложению.


1
Не используйте форматирование кавычек для текста, который не цитируется, и если он цитируется, вам необходимо указать источник.
Marquis of Lorne

0

Основные принципы сборки мусора - найти в программе объекты данных, к которым невозможно будет получить доступ в будущем, и освободить ресурсы, используемые этими объектами. https://en.wikipedia.org/wiki/Garbage_collection_%28computer_science%29

Преимущества

1) Спасает от ошибок, которые возникают, когда часть памяти освобождается, пока на нее еще есть указатели, и один из этих указателей разыменован. https://en.wikipedia.org/wiki/Dangling_pointer

2) Ошибки двойного освобождения, которые возникают, когда программа пытается освободить область памяти, которая уже была освобождена и, возможно, уже была выделена снова.

3) Предотвращает определенные виды утечек памяти, при которых программе не удается освободить память, занятую объектами, которые стали недоступными, что может привести к исчерпанию памяти.

Недостатки

1) Потребление дополнительных ресурсов, влияние на производительность, возможные задержки в выполнении программы и несовместимость с ручным управлением ресурсами. Сборка мусора требует вычислительных ресурсов для принятия решения о том, какую память освободить, даже если программист, возможно, уже знал эту информацию.

2) Момент, когда мусор действительно собирается, может быть непредсказуемым, что приводит к остановкам (паузы для сдвига / освобождения памяти), разбросанных по всему сеансу. Непредсказуемые задержки могут быть недопустимыми в средах реального времени, при обработке транзакций или в интерактивных программах.


Учебник Oracle http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/gc01/index.html

Сборка мусора - это процесс определения, какие объекты используются, а какие нет, а также удаление неиспользуемых объектов.

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

int * array = new int[size];
processArray(array); //do some work.
delete array; //Free memory

Первый шаг в этом процессе называется маркировкой. Здесь сборщик мусора определяет, какие части памяти используются, а какие нет.

Шаг 2а. При обычном удалении удаляются объекты, на которые нет ссылок, а объекты, на которые есть ссылки, и указатели остаются на свободном месте.

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

Как указывалось ранее, отмечать и уплотнять все объекты в JVM неэффективно. По мере того, как выделяется все больше и больше объектов, список объектов растет и увеличивается, что приводит к увеличению времени сборки мусора.

Продолжайте читать это руководство, и вы узнаете, как GC решает эту задачу.

Короче говоря, есть три области кучи: YoungGeneration для объектов с коротким сроком службы, OldGeneration для объектов с длительным периодом жизни и PermanentGeneration для объектов, которые существуют в течение жизненного цикла приложения, например классов, библиотек.


0

Поскольку объекты динамически выделяются оператором new , вы можете спросить, как эти объекты уничтожаются и как освобождается занятая память. В других языках, таких как C ++, вам необходимо динамически освобождать выделенные вручную объекты с помощью оператора удаления. У Java другой подход; он автоматически обрабатывает освобождение. Этот метод известен как сборка мусора .

Это работает так: когда нет ссылок на объект, предполагается, что этот объект больше не нужен, и вы можете получить память, занимаемую объектом. Нет необходимости явно уничтожать объекты, как в C ++. Сборка мусора происходит спорадически во время выполнения программы; Это не происходит просто потому, что один или несколько объектов больше не используются. Кроме того, несколько реализаций среды выполнения Java имеют разные подходы к сборке мусора, но большинству программистов не нужно беспокоиться об этом при написании программ.


-2

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.