Java Memory Quiz: Heap, GC and String Pool Practice Test
Test Java memory management with 15 questions and three programs: stack and heap, references, garbage collection, the string pool and class loading.
- Course: Java study plan
- Module: Memory and the JVM runtime
- Kind: Checkpoint — cleared at 70%
- Reading time: 30 min
- Runtime: OpenJDK 18
Checkpoint — Memory and the JVM runtime is the checkpoint that closes the Memory and the JVM runtime module: a graded quiz and whole-program exercises, passed at 70%.
Instructions
This checkpoint covers the stack and the heap, aliasing and pass-by-value, object layout, reachability and the four reference strengths, the leak shapes, generational garbage collection and the collectors, the string pool and the Integer cache, StringBuilder growth, class loading and initialisation order, the JIT, and the diagnosis toolkit with the LRU cache.
How it works. Fifteen questions and three programs; 70% on the questions and every program accepted clears the module.
Before you start, make sure you can answer:
- Where a local
int, a local reference and the object it points to each live. - Why two references to one array are an alias, and what a method can and cannot do to a caller's variable.
- What makes an object garbage, and why a cycle does not keep it alive.
- Weak versus soft references, and why
WeakHashMapwithStringliteral keys never shrinks. - Minor versus full GC, and what a log full of
Pause Fulllines means. - Why
"a" == "a"butnew String("a") != "a", and where the Integer cache ends. - The exact order of static and instance initialisers for
new Child(). - The two-line
LinkedHashMaprecipe for an LRU cache.
The programs are a tracing collector that decides what reference counting would have leaked, a bounded LRU cache with hit statistics, and an intern table that reports every hit and miss.
Common questions
Where do a local int, a local reference and its object live in Java?
The local int and the local reference both sit in the method's frame on the running thread's stack. The object the reference points to lives on the shared heap, like every object and array.
Why does a WeakHashMap with String literal keys never shrink?
String literals are interned in the string pool and stay reachable from the classes that use them, so the keys never lose their last strong reference and the collector never removes the entries.
What does a GC log full of Pause Full lines mean?
The old generation keeps filling up, or something keeps calling System.gc(). Frequent full pauses point to a memory leak, a heap too small for the live data, or medium-lived objects promoted prematurely out of the young generation.
Exercises
Tracing versus counting
Compare the two collection strategies on one object graph. Read an integer n and n object names; r and r roots; e and e edges from to. Compute:
- Tracing frees every object not reachable from a root.
- Reference counting gives each object a count = number of incoming edges + 1 if it is a root; frees every non-root object whose count is 0, and when an object is freed decrements the count of each object it points to, freeing those that reach 0 — repeat until stable.
Print tracing=<freed, natural order>, counting=<freed, natural order> and leaked=<objects tracing frees but counting does not> (- for an empty list). The leaked ones are exactly the garbage cycles.
Example: 5 then a b c d e, 1 then a, 4 then a b, c d, d c, d e →
tracing=c d e
counting=-
leaked=c d eCompact the heap
Simulate a mark–compact collector's sliding phase. Read an integer n and n blocks <id> <size> <live> in address order, starting at address 0 (live is 1 or 0). Live blocks slide down to the lowest free address, keeping their order; dead blocks are dropped. Print one line per live block <id>: <old address> -> <new address>, then freed=<total size of dead blocks> and top=<the first free address after compaction>.
Example: 4 then a 16 1, b 32 0, c 8 1, d 24 1 →
a: 0 -> 0
c: 48 -> 16
d: 56 -> 24
freed=32
top=48An intern table
Implement a string pool. Read an integer n and n words. Keep a HashMap<String, String> pool; for each word, if an equal string is already pooled print hit <word> and reuse it, otherwise print miss <word> and add it. After all words print distinct=<pool size> and saved=<total characters of the words that were hits — the memory interning avoided>. Then, using the pooled references, print identical=<true if the pooled reference for the first word == the pooled reference for the last word>.
Example: 4 then java go java rust →
miss java
miss go
hit java
miss rust
distinct=3
saved=4
identical=falseIn this module: Memory and the JVM runtime
- Stack and heap — where every value lives
- Object lifecycle, reachability and reference types
- Garbage collection — generations, pauses and the collectors
- The string pool, interning and the Integer cache
- Class loading, initialisation order and the JIT
- Diagnosing memory problems — leaks, dumps and bounded caches
- Checkpoint — Memory and the JVM runtime (this lesson)
← Diagnosing memory problems — leaks, dumps and bounded caches · Threads and Runnables — starting, joining, interrupting →