Java 对象引用、线程和垃圾收集
关于垃圾收集器,我知道的为数不多的事情之一是,它拾取没有引用的对象。 让MyClass是一个类,我通过Java 对象引用、线程和垃圾收集,java,multithreading,garbage-collection,Java,Multithreading,Garbage Collection,关于垃圾收集器,我知道的为数不多的事情之一是,它拾取没有引用的对象。 让MyClass是一个类,我通过 MyClass object = new MyClass(); 即使我的代码是通过执行 object = null; 但是没有对象引用的对象发生了什么,如下面的语句 new MyClass(); 我怀疑的是线程,我可以通过以下代码创建和执行线程 public static void main(String args[]) { new Thread() {
MyClass object = new MyClass();
即使我的代码是通过执行
object = null;
但是没有对象引用的对象发生了什么,如下面的语句
new MyClass();
我怀疑的是线程,我可以通过以下代码创建和执行线程
public static void main(String args[])
{
new Thread() {
public void run() {
try {
System.out.println("Does it work?");
Thread.sleep(1000);
System.out.println("Nope, it doesnt...again.");
} catch(InterruptedException v) {
System.out.println(v);
}
}
}.start();
}
但是线程没有对它的引用,就像你知道的,我可以通过对象引用来创建线程,但可能我不想
如果线程正在执行一个长时间运行的任务,垃圾收集器将如何对此作出反应?
新的MyClass将会发生什么;从GC的角度来看的语句。。。
GC查看所有活动线程的堆栈跟踪,因此您的线程没有来自主线程的引用,但它有来自当前正在执行的线程和新创建的线程的引用
GC从所谓的GC根中查找可访问的对象,其中一个根是所有线程。GC在所有活动线程中查找堆栈跟踪,因此您的线程没有来自主线程的引用,但它从当前正在执行的根中找到了新创建的线程
GC从所谓的GC根中查找可访问的对象,其中一个根是所有线程。JVM保留对所有正在运行的线程的引用,因此如果线程正在运行,它将不会被垃圾收集。此外,如果对象被正在运行的线程引用,则不会对其进行垃圾收集。JVM会保留对所有正在运行的线程的引用,因此如果线程正在运行,则不会对其进行垃圾收集。此外,如果对象被正在运行的线程引用,则不会对其进行垃圾收集 …没有引用的对象 让我们清楚这意味着什么。关于GC的讨论通常会区分可从GC根跟踪的对象和不可跟踪的对象 可跟踪意味着,您遵循从gc根开始的对象引用链,并最终到达相关对象。gc根基本上是程序中的所有静态变量,以及每个线程中每个活动方法调用的所有参数和所有局部变量 活动方法调用意味着调用已经发生,而相应的返回尚未发生 因此,如果某个线程中的某个活动方法引用了一个Foo实例,而Foo实例引用了一个Bar实例,而Bar实例引用了一个Baz实例;那么Baz实例是可跟踪的,并且不会被收集 在每个线程中,在线程堆栈上的run调用下面都有方法激活,其中至少有一个方法激活引用了管理线程的线程实例。因此,当线程对象所管理的线程仍在运行时,它将永远不会是GCd 另外,在JVM的黑暗心脏的某个地方,有一个所有类实例的静态列表,因此它们也不会是GCd …没有引用的对象 让我们清楚这意味着什么。关于GC的讨论通常会区分可从GC根跟踪的对象和不可跟踪的对象 可跟踪意味着,您遵循从gc根开始的对象引用链,并最终到达相关对象。gc根基本上是程序中的所有静态变量,以及每个线程中每个活动方法调用的所有参数和所有局部变量 活动方法调用意味着调用已经发生,而相应的返回尚未发生 因此,如果某个线程中的某个活动方法引用了一个Foo实例,而Foo实例引用了一个Bar实例,而Bar实例引用了一个Baz实例;那么Baz实例是可跟踪的,并且不会被收集 在每个线程中,在线程堆栈上的run调用下面都有方法激活,其中至少有一个方法激活引用了管理线程的线程实例。因此,当线程对象所管理的线程仍在运行时,它将永远不会是GCd 另外,在JVM的黑暗心脏的某个地方,有一个所有类实例的静态列表,因此它们也不会是GCd