Reputation: 1345
I'm using some fairly heavy reflection to inspect and walk through a library of classes. I want to extract and modify fields - both static and instance. Static fields are easy to find and modify; I can collect up classes, ask for lists of their fields, record the fields and inspect/alter their values.
Instance fields are different. I can collect references to their Field objects, but in order to alter their values I need to run code that instantiates objects of that type. Let's say we have no idea what this code does, but we have some method blackBox() that instantiates some objects, runs some code, does things using the library we're interested in. After it runs, I want to find instances of a class, C.
If I collect a list of all static fields, and iterate through their references far enough, will I eventually find all instances that are alive in the code? That is, I'm proposing that:
For all objects instantiated in a Java program that are not garbage-collected, there exists a chain of references starting with a static field and ending with that object.
Is this a general rule about Java programs?
EDIT: Two extra qualifiers:
Upvotes: 2
Views: 121
Reputation: 3011
This is could be a good starting point :
The concurrent collector pauses an application twice during a concurrent collection cycle. The first pause is to mark as live the objects directly reachable from the roots (e.g., objects on thread stack, static objects and so on) and elsewhere in the heap (e.g., the young generation). This first pause is referred to as the initial mark. The second pause comes at the end of the marking phase and finds objects that were missed during the concurrent marking phase due to the concurrent execution of the application threads. The second pause is referred to as the remark.
For a more deeply reading please consider:
Upvotes: 0
Reputation: 691745
No. Either you have a chain of references starting from a static field, or (and it's probably more often the case) you have a chain of references starting from a local variable on a thread's stack:
public static void main(String[] args) {
Foo foo = new Foo();
doSomethingWithFoo(foo);
}
In the above, foo migh in fact reference a whole bunch of other objects, recursively, and they're all non collectable by the GC because the main thread still has the local variable foo
in its stack.
Upvotes: 3