Сборка мусора (Местные ссылки) - PullRequest
0 голосов
/ 31 декабря 2018

У меня путаница из-за того, как GC работает в Java.

Ниже приведен фрагмент кода, который меня смущает:

private Data data = new Data();

void main() {

    for (int i = 0; i < 100 ; i++) {
       MyThread thread = new MyThread(data);
       thread.start();
    }

    System.gc();

    // Long running process

} 

class MyThread extends Thread {
    private Data dataReference;

    MyThread(Data data) {
        dataReference = data;
    }
}

В приведенном выше примере, если gc вызывается перед продолжением (// длительный процесс)

  • Будут ли локальные потоки собираться мусором?

  • Или GC пометит их (MyThread локальные ссылки) как живой, поскольку он содержит ссылку на глобальную ссылку данные ?

Ответы [ 5 ]

0 голосов
/ 31 декабря 2018

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

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

A достижимый объект - это любой объект, к которому можно получить доступ в любом потенциальном продолжающемся вычислении из любого живого потока.( JLS 12.6.1 )

Более того, поскольку действующий поток может вызывать Thread.currentThread(), объект потока Thread также должен быть доступен, пока поток является действующим... независимо от каких-либо других ссылок на него.

Однако, если ссылка на Thread объект становится недоступной до вызова метода start(), он будет иметь право на сборку мусора.Если бы это было не так, создание и не запуск Thread было бы утечкой памяти!

0 голосов
/ 31 декабря 2018

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

В Java GC работает в системе под названием Mark and Sweep.Алгоритм работает следующим образом:

  • Начните с набора корневых объектов (корней GC) и набора всех выделенных объектов.
  • Отметьте эти корни
  • Отметьтекаждый объект, достижимый из этих корней, путем рекурсивного посещения каждого поля этих объектов.
  • Когда каждый возможный объект помечен, просмотрите список всех объектов.Если элемент не помечен, освободите его.

(Это упрощение, современная реализация работает примерно так, но гораздо более изощренно).

Так что же такоекорень GC?Любой объект, сохраненный в локальной переменной, все еще находящейся в области видимости, в статической переменной, в ссылке JNI и во всех выполняющихся в данный момент потоках.

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

Но отношения всегдаспускается от корня к другим объектам.Если Foo содержит ссылку на Bar, Foo может быть удалена независимо от того, может ли быть Bar.Но если Foo не может быть удален, то и Бар не может.

0 голосов
/ 31 декабря 2018

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

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

сборщик мусора в Java

0 голосов
/ 31 декабря 2018

Нет грантополучателя, что gc будет выполнен после вызова System.gc();.System.gc() вызов просто ПРЕДЛАГАЕТ, что ВМ выполняет сборку мусора.

И thread не является целью для gc.Поток не будет очищен, пока не закончится работа.

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

0 голосов
/ 31 декабря 2018

Экземпляры MyThread могут собираться мусором только после их выполнения (т. Е. Выполняется их метод run).После завершения цикла for любые экземпляры MyThread, для которых выполняется метод run, могут быть подвергнуты сборке мусора (поскольку на них нет ссылок).

Тот факт, что каждый экземпляр MyThread содержит aссылка на экземпляр Data, который не собирает мусор, не влияет на время, когда экземпляры MyThread получают право на сборку мусора.

...