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:
- I’m only interested in sequential programs, that don’t spawn threads.
- I’m assuming that blackBox() has finished processing, and the garbage collector has run. There might be more code we want to execute later using the library (moreBlackBox()) – imagine an application that has started up, and is now paused.
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:
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
fooin its stack.