Вопрос по multithreading, java – Java-потоки и сборщик мусора [дубликаты]

18

Possible Duplicate:
Java Thread Garbage collected or not

Рассмотрим следующий класс:

class Foo implements Runnable {

  public Foo () {
       Thread th = new Thread (this);
       th.start();
  }

  public run() {
    ... // long task
  }

}

Если мы создадим несколько экземпляровFoo при выполнении

new Foo();
new Foo();
new Foo();
new Foo();

(обратите внимание, что мы не храним указатель на них).

Could those instances be removed by the garbage collector before the thread in run() ends? (In other words: is there any reference to the Foo objects?)

And, in the other hand, will those instances be removed by the GC after the thread in `run()' ends, or are we wasting memory ("memory leak")?

If either 1. or 2. are a problem, what's the right way to do it?

Спасибо

Это не дубликат. Связанный вопрос не затрагивает аспект «Будет ли он вообще собирать мусор после завершения»? (Я собирался спросить это конкретно). Он только спрашивает / отвечает аспекту «он не будет GC» во время работы ». Этот вопрос, на мой взгляд, лучше. bluenote10
Вы можете проверить это очень легко. Radu Murzea
@Quaternion, да, может быть, но формулировка этого другого вопроса действительно "запутана" и трудно понять, имхо. cibercitizen1
Вот что происходит, когда вы геймифицируете контент-контроль. Материал помечается как дубликат, когда это явно не так. Joseph Persie

Ваш Ответ

5   ответов
18
Any object which is referenced by an active thread may not be de-allocated. Yes, instances will be removed by the GC after the thread in `run()' ends. No prob.
Пожалуйста, дайте мне, где вы получите этот вывод.
2
The Foo object is referenced by the Thread. Thread is referenced during its run all the time. Therefore it will not be garbage collected. No memory leaks. Thread will end and will be garbage collected and Foo object in this process as well. It should work fine.
0

Предполагая, что вы создаете объекты в методе run, эти объекты выйдут из области видимости при выходе из метода run и будут доступны для сборки мусора. Выполнить это просто еще один метод. Использование потоков или нет не меняет поведение сборки мусора здесь в любом случае. Все, что вам нужно, это заботиться о том, когда объекты выходят из области видимости, что обычно связано с областью действия блока (блок метода, цикл, блок if и т. Д.).

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

Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded cibercitizen1
7

Запуск нового потока без указания группы потоков приведет кдобавить его в группу по умолчанию:

If group is null and there is a security manager, the group is determined by the security manager's getThreadGroup method. If group is null and there is not a security manager, or the security manager's getThreadGroup method returns null, the group is set to be the same ThreadGroup as the thread that is creating the new thread.

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

Когда поток завершается (= когдаrun() возвращается по какой-либо причине), поток удаляется из группы потоков. Это происходит в частном методеexit() который вызывается из нативного кода. Это момент времени, когда последняя ссылка на поток теряется и становится доступной для GC.

Обратите внимание, что код указывает, чтоThreadGroup может бытьnull но это не так. Различные нуль-проверки просто для того, чтобы избежать NPE в редких случаях, когда что-то идет не так. ВThread.init()вы бы получили NPE, если бы Java не могла определить группу потоков.

11
  1. Could those instances be removed by the garbage collector before the thread in run() ends? (In other words: is there any reference to the Foo objects?)

Нет. Пока работает конструктор, GC не будет собирать объект. Иначе даже самое простое:

Customer c = new Customer();

может потерпеть неудачу в то время как конструкторCustomer бежит. С другой стороны, когда вы начинаете новый поток, объект потока становится новымGC rootпоэтому все, на что ссылается этот объект, не подлежит сборке мусора.

  1. And, in the other hand, will those instances be removed by the GC after the thread in `run()' ends, or are we wasting memory ("memory leak")?

Когда поток завершен, он больше не является корнем GC. Если никакой другой код не указывает на этот объект потока, он будет собирать мусор.

  1. If either 1. or 2. are a problem, what's the right way to do it?

Ваш код просто отлично. Тем не мение:

  • starting a new thread in a constructor is a poor idea from unit-testing point of view

  • keeping a reference to all running thread might be beneficial if e.g. you want to interrupt these threads later.

Error: User Rate Limit Exceeded
Error: User Rate Limit ExceededthisError: User Rate Limit ExceededThreadError: User Rate Limit ExceededFooError: User Rate Limit ExceededFooError: User Rate Limit ExceededFooError: User Rate Limit ExceededFooError: User Rate Limit Exceeded

Похожие вопросы