可能重复:
Java线程垃圾收集或不
考虑下面的类:
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();
(注意,我们不是指针保持他们)。
能的那些情况下被垃圾收集器在线程之前被去除run()
结束? (换句话说:是否有到任何参考Foo
对象?)
而且,在另一方面,将这些实例可以通过运行`()”端线后的GC删除,还是我们浪费存储器(‘内存泄漏’)?
如果任1或2是一个问题,什么是应该做的正确方法?
谢谢
- 能的那些情况下被垃圾收集器在运行中的线程之前被移除()结束? (换句话说:是否有到富对象的任何引用?)
否。虽然构造函数运行GC不会收集的对象。 否则,即使是最简单的:
Customer c = new Customer();
的构造而可能失败Customer
正在运行。 在当你开始一个新的线程另一方面,线程对象将成为一个新的GC根 ,所以该对象引用一切都没有垃圾收集的对象。
- 而且,在另一方面,将这些实例可以通过运行`()”端线后的GC删除,还是我们浪费存储器(‘内存泄漏’)?
一旦线程完成,它不再是一个GC根。 如果没有其他代码指向该线程对象,这将是垃圾收集。
- 如果任1或2是一个问题,什么是应该做的正确方法?
您的代码就好了。 然而:
开始一个新的线程,而无需指定线程组将其添加到默认组 :
如果group为null,并且有安全管理器,该组由安全管理器的getThreadGroup法确定。 如果group为null,并且没有安全管理器,或安全管理器的getThreadGroup方法返回null,该组被设置为相同的线程组为正在创建新线程的线程。
该集团将保留对线程的引用,只要它是活的,所以它不能在这段时间内GC'd。
当一个线程终止(=当run()
返回无论何种原因),该线程被从线程组中删除。 这发生在私有方法exit()
这是从本机代码调用。 这是在时间点的最后一个参考线丢失,变得适合GC。
请注意,代码表示ThreadGroup
可以为null
,但事实并非如此。 各种空的检查只是为了避免在出现问题的极少数情况下的NPE。 在Thread.init()
你会得到的NPE如果用Java代码无法确定一个线程组。
假设你正在创建中的run方法的对象,对象将超出范围时run方法退出,然后将可用于垃圾收集。 润是另一种方法。 使用线程与否不以任何方式改变这里的垃圾收集行为。 所有你需要关心的是,当对象超出范围,这一般依赖于块作用域(方法块,while循环,if块,等等)。
所以,既然你们不守来开始与对象的任何引用,你可能要提取创建该对象到它自己的短暂的方法的逻辑。 这样,所创建的对象将不会需要不断超越该方法的范围。