首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Java线程和垃圾收集器

Java线程和垃圾收集器
EN

Stack Overflow用户
提问于 2012-04-30 16:02:00
回答 5查看 8.5K关注 0票数 21

可能重复:

Java Thread Garbage collected or not

考虑下面的类:

代码语言:javascript
复制
class Foo implements Runnable {

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

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

}

如果我们通过执行以下操作创建多个Foo实例

代码语言:javascript
复制
new Foo();
new Foo();
new Foo();
new Foo();

(请注意,我们没有保留指向它们的指针)。

  1. run()中的线程结束之前,垃圾回收器是否可以删除这些实例?(换句话说:另一方面,是否存在对运行objects?)
  2. And,的引用,这些实例是否会在‘Foo ()’中的线程结束后被GC删除,或者我们是否在浪费内存(“内存泄漏”)?
  3. 如果1.或2.有问题,正确的方法是什么?

谢谢

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2012-04-30 16:08:25

运行活动线程引用的任何对象可能不是运行实例。在‘de-allocated.

  • Yes,()’中的线程结束后,GC将删除
  1. No prob。
票数 21
EN

Stack Overflow用户

发布于 2012-04-30 16:10:32

  1. 在run()中的线程结束之前,垃圾回收器是否可以删除这些实例?(换句话说:是否有对Foo对象的引用?)

不是的。当构造函数运行时,GC不会收集对象。否则即使是最简单的:

代码语言:javascript
复制
Customer c = new Customer();

Customer的构造函数正在运行时可能会失败。另一方面,当您启动一个新线程时,线程对象将成为一个新的GC根,因此该对象引用的所有内容都不是垃圾回收的对象。

运行,另一方面,这些实例是否会在‘()’中的线程结束后被GC删除,或者我们是否在浪费内存(“内存泄漏”)?

一旦线程完成,它就不再是GC根目录。如果没有其他代码指向该线程对象,它将被垃圾回收。

  1. 如果1.或2.都有问题,正确的解决方法是什么?

你的代码很好。但是:

从单元测试的角度来看,

  • 在构造函数中启动一个新线程不是一个好主意。
  • 保留对所有正在运行的线程的引用可能是有益的,例如,如果您想要稍后中断这些线程。
票数 11
EN

Stack Overflow用户

发布于 2012-04-30 16:14:13

在不指定线程组的情况下启动新线程将发生add it to the default group

如果group为null并且存在安全管理器,则由安全管理器的getThreadGroup方法确定该组。如果组为null并且没有安全管理器,或者安全管理器的getThreadGroup方法返回null,则将组设置为与创建新线程的线程相同的ThreadGroup。

只要线程处于活动状态,组就会保留对该线程的引用,因此在此期间不能对其进行GC。

当线程终止时(=当run()出于某种原因返回时),该线程将从线程组中删除。这发生在私有方法exit()中,该方法从本机代码调用。这是对线程的最后一个引用丢失的时间点,它有资格进行GC。

注意,代码表明ThreadGroup可以是null,但事实并非如此。各种null-check只是为了在出现错误的极少数情况下避免NPE。在Thread.init()中,如果Java不能确定线程组,就会得到NPE。

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10380327

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档