2014-10-07 38 views
8

我有一个关于GC根的问题。我读到GC的根源是“Live thread”。那是什么意思? 我总是有印象,每个线程都有它自己的堆栈,堆栈的局部变量是线程的GC根,现在我很困惑。线程表示具有哪些其他类型的对象引用,它们不在帧堆栈或本地堆栈上?作为GC根的线程

其他问题是年轻一代收集使用GC根,还是只为主要算法?

感谢

更新: 好难过,所以要保持它的简单:我读过这篇短文:yourkit.com/docs/java/help/gc_roots.jsp,有一个“主题”选项, GC根,究竟是什么意思,该线程是GC根?什么样的对象被Thread GC根引用,它没有被堆栈引用?为什么这两个类别不同?

+1

你的问题很混乱。 1)当然,只有活动的线程才算GC根源。 2)什么是“线索表示”? 3)静态变量是非堆栈GC根。 4)每个GC变体都考虑了GC根源;它不可能*不*考虑到它们。 – 2014-10-07 09:36:13

+0

对不起,为了保持简单:我读过这篇简短的文章:http://www.yourkit.com/docs/java/help/gc_roots.jsp,并且有一个“Thread”选项作为GC根,究竟是什么这是否意味着该线程是GC根?什么样的对象被Thread GC根引用,它没有被堆栈引用?为什么这两个类别不同? – alobodzk 2014-10-07 09:57:05

+0

@MarkoTopolnik我不认为静态变量是根,否则类加载器将永远不会卸载。 – 2014-10-07 09:59:03

回答

3

我读到GC根的一个是“Live thread”。那是什么意思?

活动线程是一个已启动且尚未终止的线程。

什么其他类型的对象引用不在线程堆栈或本地堆栈上线程表示具有?

无。

当他们说一个(活)线程是一个GC根时,它们的意思是(实际上)所有线程的堆栈帧中的值。

(“帧栈”和“本地栈”是同一回事。)

......究竟这是否意味着线程是一个GC根?

这意味着线程的堆栈是一个GC根,并且所有线程的堆栈帧中所有活动变量的内容都是可到达的。

这些东西都是有效的说相同的东西

+0

感谢您的澄清! – alobodzk 2014-10-09 14:01:23

+0

我怀疑yourkit的分类是任意的。这些区别肯定意味着*某事*。 – 2014-10-11 17:57:46

+0

帧堆栈用于解释代码,本地堆栈由解释器本身和JIT编译代码使用。 – 2014-10-11 18:24:06

0

想象一下,当方法退出对象消失时(引用超出范围并且任何堆分配的内存符合GC标准),将使用java线程对象local new'ed。如果使用相同的方法启动线程,则现在该线程对象的实时时间以及它引用的任何内容都与活动线程的运行时间相关联。在线程退出之前,仍然从正在运行的线程引用的内存不符合GC的要求,并且该线程被称为GC根目录。

线程可以通过堆栈或堆以两种不同的方式分配内存。堆栈存储不是GC'ed,但在当前堆栈帧解开时回收。当您在代码中使用“新”时,堆存储通常会被分配(请注意,新并不总意味着堆存储参见“转义分析”)。堆是GC'ed。

了解更多关于GC根的一个好方法是将正在运行的Java应用程序的堆转储并加载到Visual VM或Eclipse MAT中,从那里您应该能够检查GC根。

年轻一代的收集将使用GC根源,GC根不符合GC的条件,但根据给定的算法讨论会更好。

0

JVM对其线程进行分区,其中一些专门用于垃圾收集,一些用于其他内部JVM任务,另一些用于执行用户提供的可执行程序部分。

在这种情况下,可达意味着用户执行线程可以访问。这包括绑定从public static void main(String[] args)运行的第一个线程以及从该线程启动的所有线程,减去无法访问或完成的线程。