是否所有非垃圾收集的对象最终都是静态引用的?

时间:2012-09-24 15:20:31

标签: java reflection static garbage-collection instance

我正在使用一些相当重的反思来检查和遍历一个类库。我想提取和修改字段 - 静态和实例。静态字段易于查找和修改;我可以收集课程,询问他们的领域列表,记录字段并检查/改变他们的价值观。

实例字段不同。我可以收集对其Field对象的引用,但是为了改变它们的值,我需要运行实例化该类型对象的代码。假设我们不知道这段代码是做什么的,但我们有一些方法blackBox()实例化一些对象,运行一些代码,使用我们感兴趣的库做一些事情。运行后,我想找到一个实例class,C。

如果我收集所有静态字段的列表,并且足够多地遍历它们的引用,我最终会找到代码中存活的所有实例吗?也就是说,我建议:

  

对于在Java程序中实例化的非垃圾收集的所有对象,存在一系列以静态字段开头并以该对象结束的引用。

这是关于Java程序的一般规则吗?

编辑:两个额外的限定符:

  1. 我只对顺序程序感兴趣,不会产生线程。
  2. 我假设blackBox()已完成处理,垃圾收集器已运行。可能会有更多的代码要在以后使用库执行(moreBlackBox()) - 想象一下已经启动的应用程序,现在暂停了。

2 个答案:

答案 0 :(得分:3)

没有。要么你有一个从静态字段开始的引用链,要么(并且可能更常见的情况)你有一个从线程堆栈上的局部变量开始的引用链:

public static void main(String[] args) {
    Foo foo = new Foo();
    doSomethingWithFoo(foo);
}

在上面,foo migh实际上以递归方式引用了大量其他对象,并且它们都是GC无法收集的,因为主线程在其堆栈中仍然具有局部变量foo。 / p>

答案 1 :(得分:0)

这可能是一个很好的起点:

  

并发收集器在a期间暂停应用程序两次   并发收集周期。第一个停顿是标记为现场   可以从根直接访问的对象(例如,线程上的对象)   堆栈,静态对象等)和堆中的其他地方(例如,堆栈)   年轻一代)。第一次暂停被称为初始   标记。第二次暂停是在标记阶段结束时发现的   由于的并发标记阶段遗漏的对象   应用程序线程的并发执行。第二次停顿   被称为评论。

如需更深入阅读,请考虑:

Oracle Garbage Collector doc