Малые и большие циклы GC - PullRequest
       39

Малые и большие циклы GC

0 голосов
/ 14 октября 2019

AFAIK, Java GC имеет незначительные GC (низкая стоимость) и основные циклы GC (высокая стоимость). Если объект находится в локальной области видимости, он очищается в второстепенном ГХ. Если ссылка на объект хранится где-то еще в коде, то он очищается в главном GC.
Так, например,

void f() {
   A a = new A();
   a.doSomething();
}

Согласно моему описанию (если это правда, конечно), объект a являетсяубирается в минорной сборке. Как насчет

void f() {
   A a = new A();
   B b = new B();
   b.doSomething(a);
}

Здесь объект a передается в качестве параметра методу doSomething B, и, возможно, B сохраняет ссылку в самом B, но мы не знаем. В этом случае объект a будет очищен в младшем или главном ГХ?

Ответы [ 2 ]

0 голосов
/ 15 октября 2019

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

Предположим, вы используете HotSpot с G1, поскольку есть несколько других альтернатив, которые работают по-разному (например, C4 вЗинг из Азула, на которого я работаю).

Куча разделена на две области, называемые молодым и старым поколением. Когда объекты впервые выделяются, пространство предоставляется из пространства Эдема, которое является частью молодого поколения (иногда крупные объекты выделяются непосредственно в старом поколении. Но давайте будем простыми, как в вашем примере). Распределение в пространстве Eden использует простой метод натяжения указателя, что приводит к очень быстрому распределению.

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

Старый ген. является отдельной логической областью памяти и использует различные алгоритмы для освобождения места и устранения фрагментации. Это основная коллекция.

Когда эти коллекции происходят, определяется не тем, где расположен объект, а тем, когда виртуальная машина решает, что коллекция необходима. Это будет определяться тем, когда пространство Eden исчерпано или когда в старом поколении появится свободное место. падает ниже определенного порога.

В вашем первом примере нет никакой гарантии, что объект 'a' будет собран во время второстепенного сбора мусора. Если doSomething () занимает много времени, и есть другие потоки, выделяющие много объектов, может произойти несколько второстепенных GC, и «a» может в конечном итоге перейти в старое поколение. (и собраны как часть основного GC).

В случае вашего второго примера, если doSomething () быстро вернулся и нигде не записал ссылку на 'b', то и 'a', и 'b' можно было бы собрать как часть вспомогательного GC.

0 голосов
/ 15 октября 2019

Вы не можете сказать, просто посмотрев на код. GC будет работать в зависимости от спроса, и частота GC будет варьироваться для каждого запуска программы и среды. Частота циклов GC (и реализация JVM) будет затем определять, будет ли объект собираться, пока он еще находится в поколении Young , или он будет повышен до Old gen. Находясь в старом поколении, объект все еще можно собирать в «параллельной» фазе (в зависимости от сборщика) и не обязательно во время полной остановки мира GC.

Это может дать вам хороший обзорвесь процесс: https://www.oracle.com/webfolder/technetwork/tutorials/obe/java/gc01/index.html

Кроме того, это хорошая статья для понимания различий между второстепенным, основным и полным GC: * ​​1008 *https://plumbr.io/blog/garbage-collection/minor-gc-vs-major-gc-vs-full-gc

...