A Java memory leak, and a bounded fix
The GC never frees what is reachable. The bounded map keeps memory flat however many requests arrive (LinkedHashMap access order is Topic 9.6).
The garbage collector frees objects that can no longer be reached from any GC root, so you never free memory by hand. Modern JVMs split the heap into generations because most objects die young, and offer collectors with different goals: G1 (the default since Java 9) balances throughput and pauses, ZGC and Shenandoah keep pauses around a millisecond, Parallel maximises throughput.
Change the code and press Run (Ctrl+Enter). Try to predict the output first, then break it on purpose and read the error. Your edits are saved and match the lesson page.
Practice questions
Write the code in the editor, run it, then open the model answer to compare.
Extend the mark-and-sweep model so oldCart becomes reachable again by adding it as a second root, and print the new garbage list.
Write an LRU cache of capacity 3 with LinkedHashMap, insert keys 1 to 5, read key 3 and insert key 6; print the keys.
Show the difference between a GC root reference and a local that is out of scope: write a method that builds a big list and returns only its size, and explain in a comment why the list is collectable after the method returns.
Explain it without notes
How does the JVM decide that an object is garbage? What are GC roots?
Explain the generational hypothesis and how a minor GC works.
Compare G1, ZGC and Parallel GC. When would you pick each?
What is a memory leak in Java, and how would you find one?
Expected output
leaky map entries: 10000 (10000 KB of arrays kept alive)
bounded map entries: 100
oldest kept key: 9901
after touch + put, oldest: 9902