我正在使用一些相当重的反思来检查和遍历一个类库。我想提取和修改字段 - 静态和实例。静态字段易于查找和修改;我可以收集课程,询问他们的领域列表,记录字段并检查/改变他们的价值观。
实例字段不同。我可以收集对其Field对象的引用,但是为了改变它们的值,我需要运行实例化该类型对象的代码。假设我们不知道这段代码是做什么的,但我们有一些方法blackBox()实例化一些对象,运行一些代码,使用我们感兴趣的库做一些事情。运行后,我想找到一个实例class,C。
如果我收集所有静态字段的列表,并且足够多地遍历它们的引用,我最终会找到代码中存活的所有实例吗?也就是说,我建议:
对于在Java程序中实例化的非垃圾收集的所有对象,存在一系列以静态字段开头并以该对象结束的引用。
这是关于Java程序的一般规则吗?
编辑:两个额外的限定符:
答案 0 :(得分:3)
没有。要么你有一个从静态字段开始的引用链,要么(并且可能更常见的情况)你有一个从线程堆栈上的局部变量开始的引用链:
public static void main(String[] args) {
Foo foo = new Foo();
doSomethingWithFoo(foo);
}
在上面,foo migh实际上以递归方式引用了大量其他对象,并且它们都是GC无法收集的,因为主线程在其堆栈中仍然具有局部变量foo
。 / p>
答案 1 :(得分:0)
这可能是一个很好的起点:
并发收集器在a期间暂停应用程序两次 并发收集周期。第一个停顿是标记为现场 可以从根直接访问的对象(例如,线程上的对象) 堆栈,静态对象等)和堆中的其他地方(例如,堆栈) 年轻一代)。第一次暂停被称为初始 标记。第二次暂停是在标记阶段结束时发现的 由于的并发标记阶段遗漏的对象 应用程序线程的并发执行。第二次停顿 被称为评论。
如需更深入阅读,请考虑: