How Java Allocates, Tracks, and Reclaims Memory

UPI Study › Courses › Data Structures and Algorithms › Free lessons › Lesson 17.7 Free with a free account

How Java Allocates, Tracks, and Reclaims Memory

Data Structures and Algorithms · Chapter 17: Graphs and MemorySection 17.7 · lesson 84 of 879 min · free with a free account

← Solving Real Problems by Modeling Them as NetworksNext lesson: Why Frequently Used Data Lives in Faster, Smaller Memory →

Earn 3 college credits for Data Structures and AlgorithmsRecommended for credit by NCCRS · Computer Science 251 · self-paced · one payment, lifetime access

In this lesson

How the stack, heap, references, and garbage collector manage memory.

  • Distinguish what Java stores on the stack from what it stores on the heap
  • Predict the effect of copying and passing references to objects and arrays
  • Explain reachability-based garbage collection and generational collection
  • Recognize and fix memory leaks in data structures

Free study notes

Get this lesson's notes by email

The key points and 4 practice questions with answers, in your inbox. One email, free.

One email. Unsubscribe in one click.

Transcript

Everything said in the video, section by section (1,320 words). Read along, or search it.

Opening Question

A Desk, a Warehouse, and a Janitor

Think of a desk and a warehouse. The desk holds the papers for the job in hand, and it's cleared the moment the job ends. The warehouse holds everything that must outlast one job. An item stays on its shelf while somebody holds a ticket that leads to it. When the last ticket is gone, a janitor clears the shelf. Java works the same way: the stack is the desk, the heap is the warehouse, references are the tickets, and the garbage collector is the janitor. So how can a program whose data structure works perfectly still run out of memory?

Stack and Heap

Frames on the Stack, Objects on the Heap

Every running thread owns a stack, a pile of frames. A method call puts a new frame on top, holding that call's parameters and local variables. The frame vanishes the instant the method returns, with no cleanup work at all. A primitive, like an int, sits right inside the frame. Any other local holds only a reference. The object itself lives on the heap, one large pool shared by every thread. Everything made with new, every array included, lives there, until no reference can reach it.

Stack Overflow

Recursion With No Stopping Condition

A stack has a fixed size per thread. This method calls itself with no stopping condition, so each call adds one more frame. Eventually there's no room for another, and Java throws a StackOverflowError, which can be caught. Run it. On one test machine it took roughly twenty thousand calls or more, and the exact count changed between runs. So recursion tens of thousands of levels deep, down a long linked list or a badly unbalanced tree, can overflow the stack while the heap is nearly empty.

Allocation

Object Headers and Boxed Number Costs

What does new do? It finds room in the part of the heap for new objects, sets every field to its default, runs the constructor, and hands back a reference. Finding room is fast. Free memory there is handed out in order, like tearing the next sheet off a pad. Every object starts with a header, and its size rounds up to a multiple of eight bytes. Measured on 64-bit Java 21, a Point with two ints takes 24 bytes. An int array of ten takes 56. An Integer array of ten is also 56, but it holds only references. Each boxed number is another 16-byte object. So a thousand boxed numbers above 127 take about 20,016 bytes, against 4,016 for an int array: about five times as much.

References

Copying a Reference, Not the Object

A variable of an object type holds a reference. So copying the variable copies the address, never the object. Run it. The primitive y was a true copy, so changing it left x alone. But after b equals a, there's one array with two names. Setting b of zero to 99 shows up through a. Once b is pointed at a new array, a keeps the old one. A called method can change the shared array, as poke does. But it can't re-aim the caller's variable, as rebind tries to, because it only received a copy of the reference.

Quick Check

Three Variables and Two Arrays

Quick check. Three variables, two arrays. Follow which name points where, and which array each change lands in. What does the last line print? Pause and predict. One, seven. b briefly named a's array, but then it was pointed at a new one, so b of zero equals nine changed only the new array. c, though, is another name for a's array. So c of one equals seven lands in a.

Garbage Collection

Reachability From the Roots

Java has no operation to free an object. The garbage collector uses one rule: an object may be reclaimed once the program can no longer reach it. The starting points are the roots: the locals and parameters in active frames, and the static fields. An object is reachable if some chain of references leads to it from a root. The collector marks everything it can reach, then reclaims whatever wasn't marked. Because the rule is about reachability, not counting references, a cycle doesn't protect anything. This program links a and b to each other, and watches them through weak references, which don't keep an object alive. Run it. While the locals hold them, both survive a collection. Once both locals are null, the pair is reclaimed, even though they still point at each other. Now, a caution. Setting a variable to null frees nothing by itself: it removes one ticket. And System.gc is only a request. It's used here so the test doesn't have to wait.

Quick Check

An Unreachable Cycle Is Garbage

Quick check. Here, a is a local that keeps living. a points to b, b points to c, and c points back to b. Then the program cuts the link from a to b, and asks for a collection. What do the two lines print? Pause and predict. Both false. The only root here is the local a, and after the cut, no chain of references leads from it to b or c. b and c still point at each other, but a cycle with no path from a root is just garbage.

Generations

Most Objects Die Young

Studies of real programs keep finding the same thing: most objects die young. So collectors split the heap into generations. New objects go into Eden. When Eden fills, a young collection copies the few survivors out and empties the rest at once. Its cost follows the survivors, not the garbage. Objects that keep surviving are promoted to the old generation. That's collected rarely, in a full collection, which examines the whole heap and pauses much longer. In one test, making 20 million short-lived arrays took 89 young collections, no full one, and 13 milliseconds of pause in all. Keeping just one array in 40 forced a full collection, and the total pause grew to 216 milliseconds.

Memory Leak

A Stale Slot in an Array Stack

The collector frees everything unreachable, so Java can't forget to free memory. It can still leak. A leak is an object you'll never use again that's still reachable. Leaks hide in data structures, because a structure is exactly a set of references keeping things alive. The first pattern is a stale slot. An array-based stack tracks its top with a counter. A pop that only lowers the counter leaves the old reference in the slot above the top. The stack treats that slot as empty, but the collector sees an ordinary reference. Run it: ten one-megabyte arrays, pushed, popped, then a collection. The leaky stack is empty by its own count, yet all ten arrays survive. The safe pop clears the slot, and all ten are released.

Memory Leak

Entries That Are Never Removed

Java's own ArrayList clears the slot when it removes an element. The trap appears when you write your own array-backed structure. The second pattern is entries never removed: a static list, a registry of listeners, a history of requests. If a program only adds, its heap use only grows. In one test, a history that kept every one-kilobyte buffer grew about a megabyte per thousand buffers. A window of the latest thousand stayed flat at two. With the heap capped at 16 megabytes, the history ran out of memory after 14,114 entries. Anything that remembers needs a rule for forgetting.

Memory Leak

Capacity Kept After Clearing

The third pattern is capacity kept after the elements are gone. A dynamic array grows, but it doesn't shrink when you remove things. In one test, an ArrayList of 3 million boxed numbers used 63 megabytes. Clear dropped that to 17: the numbers were released, but the big backing array stayed. trimToSize gave the rest back, down to one megabyte. To spot a leak, watch the heap after each collection: a steady saw-tooth is healthy, a creeping level is not.

Key Takeaways

Java Memory in Brief

To sum up. Frames live on the stack and vanish on return. Objects live on the heap. Copying a reference never copies the object. An object is reclaimed once no chain from a root reaches it, cycles included. Young collections are cheap, full ones are not. And a leak is reachable memory you'll never use: clear stale slots, limit what you remember, and trim capacity.

About Data Structures and Algorithms at UPI Study

Data Structures and Algorithms (Computer Science 251) is a self-paced online course of 87 video lessons in 17 chapters, from Java and object-oriented design to arrays, linked lists, recursion, stacks and queues, trees, heaps, hash tables, sorting and graphs. It carries a NCCRS credit recommendation for 3 semester credits.

Every lesson transcript is free on pages like this one, and the videos are free with a free UPI Study account. Enrolling adds a practice quiz after each lesson, the graded work and final exam that earn the credit, lifetime access, and an official transcript on completion. UPI Study has helped over 130,000 students with college credits. ACE and NCCRS have over 2,100 cooperating colleges that will consider accepting credits; the final decision is with the universities.

Compare: Discrete Math vs Data Structures and Algorithms · Intro to Java vs Data Structures and Algorithms

Why take it here

Why students take Data Structures and Algorithms with UPI Study

How programs store and search dataData Structures and Algorithms teaches how to organize data and measure how fast code runs: arrays, linked lists, stacks, queues, trees, heaps, hash tables, sorting and graphs, all written in Java. It is a core course in computer science and software degrees.
Credit at a fraction of the priceThe same 3 credits can cost $750 or more at a US college. Here it is one payment, self-paced, with lifetime access.
Finish your degree soonerTransfer credits reduce the courses you still owe, so you can graduate earlier or lighten a heavy semester.
Strengthen an applicationA completed college-level course on an official transcript shows admissions and scholarship committees you can do the work.
Study on your own scheduleNo start dates, no deadlines. Watch the lessons, practice, and take the final when you are ready.
130,000+students helped with college creditsACE and NCCRS have over 2,100 cooperating colleges that will consider accepting credits; the final decision is with the universities.

Where the credit goes

Universities that work with NCCRS

Data Structures and Algorithms carries a NCCRS credit recommendation. These universities work with NCCRS; some are UPI Study's signed partners. ACE and NCCRS have over 2,100 cooperating colleges that will consider accepting credits; the final decision is with the universities.

Find my college → Not listed? Ask Athena in the corner of this page, or book a 15-minute call.

FAQ

Questions students ask us

About How Java Allocates, Tracks, and Reclaims Memory

What is the difference between the stack and the heap in Java?
In Java, each thread's stack holds frames with a method call's parameters and local variables, and a frame vanishes the instant the method returns. The heap is one large pool, shared by all threads, that holds every object and array made with new until no reference can reach it. A primitive local such as an int sits inside the frame, while an object-type local holds only a reference.
Is Java pass by reference or pass by value?
Java passes every argument by value, and for an object or array that value is a copy of the reference. So a called method can change the shared object, for example with arr[0] = 99, and the caller sees the change. But reassigning the parameter, as in arr = new int[3], only re-aims the method's own copy and leaves the caller's variable pointing at the original array.
How does Java garbage collection decide what to free?
Java's garbage collector reclaims an object once no chain of references leads to it from a root, meaning a local or parameter in an active frame or a static field. The collector marks everything reachable and reclaims the rest. Because the rule is reachability rather than reference counting, two objects that point only at each other are still collected. Setting a variable to null removes one reference, and System.gc() is only a request.
Can Java have memory leaks?
Yes, Java can leak memory when objects the program will never use again stay reachable. Common causes are an array-based stack whose pop lowers the counter without clearing the slot, collections or listener registries that only ever grow, and a dynamic array that keeps its large backing array after clear. Fixes include setting popped slots to null, limiting what is remembered, and calling trimToSize on an ArrayList.

About the Data Structures and Algorithms course

How many college credits is Data Structures and Algorithms?
Data Structures and Algorithms (Computer Science 251) carries a NCCRS credit recommendation for 3 semester credits. ACE and NCCRS have over 2,100 cooperating colleges that will consider accepting credits; the final decision is with the universities.
How much does Data Structures and Algorithms cost and what is included?
$250, paid once, with lifetime access: all 87 video lessons, a practice quiz after each, the graded work and final exam, and an official transcript when you finish. Students who want several courses choose UPI Study PRO instead.
Which universities accept UPI Study credits?
UPI Study has signed partner agreements with universities such as Thomas Edison State University, University of the People and Charter Oak State College, and works with universities such as Penn State, SNHU and SUNY. ACE and NCCRS have over 2,100 cooperating colleges that will consider accepting credits; the final decision is with the universities. Use "Find my college" on this page to check yours.
How long does Data Structures and Algorithms take?
It is self-paced with no deadlines. The 87 lessons total about 15 hours of video; most students add reading and practice time and finish in a few weeks to a few months, on their own schedule.
How are the exams done?
Quizzes and assignments are online in the course. The final exam is taken online with proctoring; a person on the UPI Study team checks assignments, usually within two days.
How do my credits reach my college?
When the course shows 100% complete, request the official transcript from your dashboard. It is sent to the college you name, and you can send it to more than one. Check your college first with "Find my college" on this page, or ask Athena.

Ready for the full course? Earn 3 credits in Data Structures and Algorithms.

87 video lessons, a quiz after each one, and the graded work that earns the credit. Recommended for credit by NCCRS.

Data Structures and Algorithms
3 credits · NCCRS
Enroll →