The JVM manages runtime execution and memory areas, while application references still decide which object graphs remain reachable.
Java JVM interview: reachability, publication and diagnostic evidence
Java 8+. This is a complete program using JDK classes.
Can a garbage-collected application leak memory?
Yes. A registry, queue, cache or listener list can retain objects that are no longer useful. They remain reachable and therefore are not garbage merely because business logic stopped needing them. Follow a retained object’s path to a root before choosing a cleanup change.
Are references and their objects the same thing?
A local reference can point to a shared heap object. Reassigning that reference does not replace another caller’s reference, and mutating the object can still be visible through other aliases. The program copies a byte payload at its ownership boundary so later source mutation cannot edit the retained bytes.
Does volatile repair a compound update?
No. Volatile visibility and ordering do not make read-modify-write increments indivisible. Use the operation’s actual synchronization contract, such as an atomic update or a lock that protects the whole invariant.
What evidence is needed for a performance claim?
Distinguish warmup, steady-state work, allocation rate, lock waiting and storage latency. A short run can include class loading and JIT work. A retained heap investigation and a CPU profile also answer different questions. Pick a repeatable workload and report the toolchain and measurement limits.
Working program
import java.util.Arrays;
public class PayloadOwnershipProbe {
static final class StoredPayload {
private final byte[] bytes;
StoredPayload(byte[] input){bytes=input.clone();}
byte[] snapshot(){return bytes.clone();}
}
public static void main(String[] args){
byte[] incoming={1,2};StoredPayload stored=new StoredPayload(incoming);
incoming[0]=9;
byte[] first=stored.snapshot();first[1]=8;
System.out.println(Arrays.toString(stored.snapshot()));
System.out.println(Arrays.toString(incoming));
}
}Output
[1, 2]
[9, 2]Costs and boundaries
Each payload copy uses O(n) byte work and O(n) storage. That ownership choice avoids alias mutation but can be costly for large payloads; immutable slices or bounded buffers need a different contract. Exact object sizes and collector behavior depend on the JVM configuration.
Common Mistakes
- Do not equate useful objects with reachable objects.
- A volatile counter increment can still lose updates.
- Avoid fixed object-size claims without identifying the runtime layout.
