skip to content

Strong References

An ordinary variable is a strong reference, and an object reachable from a GC root through strong references is never collected. This is the baseline the weaker java.lang.ref types are defined against, and the reason most leaks are just unintended strong reachability.

part ofJavaoverview, primer and where to startread it →
on this pageshow

questions

4

What is a strong reference in Java, and how does it affect whether an object can be garbage collected?

level: juniorimportance: must knowfreq 70%

answer

  1. Default reference = ordinary variable assignment
  2. Reachable from a GC root => never collected
  3. Drop all strong refs (null / out of scope) to make collectible
  4. Baseline that Soft/Weak/Phantom are defined against
  5. Object lives on heap; reference is the handle

basics

~20 s

A strong reference is an ordinary variable that points to an object, like String s = new String(). As long as such a reference exists and can be reached by the program, the garbage collector will never delete that object.

solid answer

~50 s

A strong reference is the default, everyday reference you create whenever you write a normal variable assignment such as Object o = new Object(). It is the strongest kind of reference: the garbage collector (GC) will never reclaim an object while a live, reachable strong reference to it exists. An object becomes eligible for collection only once no strong reference can reach it from a GC root (a starting point the GC trusts as always-live, such as a local variable on an active thread's stack or a static field). The weaker reference types in java.lang.ref (SoftReference, WeakReference, PhantomReference) are all defined by contrast with this baseline: they let the GC reclaim the object earlier under specified conditions. To make an object collectible you drop all strong references to it, for example by setting the variable to null or letting it go out of scope.

code

java · 5 lines
java
Object data = new Object(); // 'data' is a strong reference; object is reachable
use(data);
data = null;                // last strong reference dropped
// The object is now unreachable from any GC root and eligible for collection
System.gc();                // a *request*, not a guarantee, that the GC runs

go deeper

for a junior

Can state that a strong reference is a normal variable and that an object with a live strong reference is never collected; knows null / out-of-scope makes it collectible.

for a middle

Frames survival in terms of reachability from GC roots, distinguishes 'eligible for collection' from 'collected', and knows System.gc() is only a hint.

for a senior

Explains why strong reachability overrides weaker reference types, why isolated cycles are still collected (reachability, not counting), and when explicit nulling is actually warranted (long-lived fields/collections).

for a principal

Connects the language-level strong reference to the platform reachability/GC-root model, reasons about how strong reachability underlies cache and leak design decisions, and can articulate the contract that the java.lang.ref types are layered on top of.

## What a reference is In Java you almost never touch objects directly. An object lives in a region of memory called the **heap**. A **reference** is a value (think of it as a typed pointer / handle) that lets your code reach that heap object. When you write: ```java String s = new String("hi"); ``` `new String("hi")` allocates a `String` object on the heap, and `s` is a variable holding a **reference** to it. `s` is not the object; it points to the object. ## What 'strong' means A **strong reference** is just the ordinary, default kind of reference — the one you get from a normal assignment. The word 'strong' only matters by contrast: the `java.lang.ref` package adds three *weaker* reference types (`SoftReference`, `WeakReference`, `PhantomReference`) that give the garbage collector permission to reclaim the object earlier. A strong reference gives no such permission. It is the strongest claim you can stake on an object's survival. ## Garbage collection and reachability Java is a **managed** language: you do not free memory manually. A background process, the **garbage collector (GC)**, periodically reclaims objects you can no longer use, so their memory can be reused. How does the GC decide what is 'no longer used'? It uses **reachability**. The GC starts from a set of trusted always-live roots, called **GC roots** — for example: local variables and parameters on the call stack of every live thread, `static` fields of loaded classes, JNI references, and a few others. From those roots it follows references object-to-object, marking everything it can reach. Anything it can reach is **live**; anything it cannot reach is **unreachable** and may be collected. The key rule for this topic: > **An object is kept alive as long as it is reachable from a GC root through a chain of strong references.** While such a chain exists, the GC will never collect the object. So a strong reference does not by *itself* pin an object — it pins the object only when the reference is part of a chain that starts at a GC root. (A strong reference that is itself unreachable cannot save anything; e.g. two unreachable objects pointing at each other are both collectible — this is why Java does not leak on reference cycles.) ## Making an object collectible To let the GC reclaim an object you must drop every strong reference that reaches it from a root. Two common ways: 1. **Let the variable go out of scope** — when a method returns, its local variables disappear, so the references they held no longer count. 2. **Reassign or null it** — `s = null;` or `s = somethingElse;` removes that particular strong reference. ```java byte[] big = new byte[100_000_000]; // strong reference -> array is pinned big = null; // last strong ref dropped -> array now collectible ``` Note: setting to `null` matters mostly for **long-lived** references (fields, static collections). For ordinary short-lived locals, scope exit handles it and explicit nulling is unnecessary noise. ## Why this is the baseline Every weaker reference type is *defined* relative to this rule. A `WeakReference`'s target is collected at the next GC once only weak references remain; a `SoftReference`'s target survives until the JVM is under memory pressure. But the moment you keep even one **strong** reference to those same targets, the weaker reference's special behavior is overridden and the object stays alive — because reachability through a strong reference always wins. Understanding strong references is therefore the foundation for understanding caches, `WeakHashMap`, listeners, and most Java memory leaks (which are simply unintended strong reachability). ## Reachability vs. the platform notion 'Reachability' and 'GC roots' are really properties of the **JVM platform** (the runtime that runs all JVM languages), not of Java the language. The *strong reference* is the Java-language-level handle; *reachability from a GC root* is the platform mechanism that decides survival. They work together: the reference is what you write, reachability is how the runtime interprets it.

  • Does setting a reference to null force the object to be collected immediately?
    No. It only makes the object eligible for collection by removing that strong reference. The GC decides when (or whether) to actually reclaim it; System.gc() is merely a hint the JVM may ignore.
  • If two objects strongly reference each other but nothing else points to them, are they collected?
    Yes. Java's GC uses reachability from GC roots, not reference counting, so an isolated cycle of strong references that is unreachable from any root is collectible.

A strong reference is like keeping a book checked out of the library in your name: as long as your name is on it (and you can be found), the library will never reshelve or recycle it. The weaker reference types are like reservation notes the library is allowed to discard when it needs the shelf space.

saying these in an interview costs you the question

  • Claiming a strong reference 'pins' an object even when the reference itself is unreachable from a GC root.
  • Saying setting a variable to null immediately frees/deletes the object (it only makes it eligible).
  • Believing Java uses reference counting, so cyclic strong references leak (it uses reachability).
  • Confusing the reference (a handle) with the object (heap memory).

context

open as a page

How does a strong reference differ from soft, weak, and phantom references in terms of when the garbage collector may reclaim the referent?

level: middleimportance: must knowfreq 62%

basics

~20 s

A strong reference keeps an object alive as long as it is reachable. Soft references are cleared only under memory pressure, weak references at the next GC once no strong refs remain, and phantom references are used only for post-cleanup notification.

open as a page

How can code that uses only ordinary strong references still cause a memory leak in a garbage-collected JVM?

level: seniorimportance: should knowfreq 58%

basics

~20 s

Even with a GC, you leak when objects stay strongly reachable but are never used again. Things like an ever-growing static list, listeners never removed, or ThreadLocals not cleared keep strong references alive, so the GC can't reclaim them.

open as a page

Explain how strong reachability from GC roots determines object liveness, and why this is a JVM platform mechanism rather than a Java language feature.

level: principalimportance: should knowfreq 40%

basics

~20 s

The JVM keeps an object alive if it can be reached from a starting point it trusts (a GC root) by following references. The strong reference is the Java keyword-free, ordinary handle you write; reachability from roots is the runtime rule the JVM applies to decide what survives.

open as a page