mtrc
mtrc

Reputation: 1345

Are all non-garbage-collected objects eventually referenced statically?

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:

  1. I'm only interested in sequential programs, that don't spawn threads.
  2. 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.

Upvotes: 2

Views: 121

Answers (2)

pedr0
pedr0

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:

Oracle Garbage Collector doc

Upvotes: 0

JB Nizet
JB Nizet

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

Related Questions