Logo
Logo
Home
Archive
AI Agent Notes
Advertise
YouTube
Login
Sign Up
Logo
  • Home
  • Posts
  • 🦥 What Is Memory and Why Does It Leak?

🦥 What Is Memory and Why Does It Leak?

Jun 3, 2025

Sponsored by

Hello fellow sloths!

Welcome to this week’s Sloth Bytes. I hope you had an amazing week! 😁

Your career will thank you.

Over 4 million professionals start their day with Morning Brew—because business news doesn’t have to be boring.

Each daily email breaks down the biggest stories in business, tech, and finance with clarity, wit, and relevance—so you're not just informed, you're actually interested.

Whether you’re leading meetings or just trying to keep up, Morning Brew helps you talk the talk without digging through social media or jargon-packed articles. And odds are, it’s already sitting in your coworker’s inbox—so you’ll have plenty to chat about.

It’s 100% free and takes less than 15 seconds to sign up, so try it today and see how Morning Brew is transforming business media for the better.

Check it out

What Is Memory and Why Does It Leak?

Ever wondered why a long-running server slowly eats more memory, or why a game’s memory footprint keeps climbing after repeatedly loading and unloading the same level? A memory leak is one possible cause—but rising RAM usage can also come from intentional caches, fragmentation, allocator behavior, or a workload that genuinely needs more live data.

5 bytes in 1 blocks are definitely lost in loss record 1 of 1

Congrats, you've met the memory leak!

One of programming's silent killer.

Let's talk about what memory actually is, why it "leaks," and how to stop your programs from becoming digital hoarders.

Memory: Your Program's Workspace

Think of your computer's memory (RAM) like a massive whiteboard. When your program runs, it writes stuff on the board:

name = "Sloth"           # Write "Sloth" on the board
score = 100             # Write "100" somewhere else
inventory = ["sword"]   # Write a list over here

Unlike your hard drive (permanent storage), RAM is temporary. When your program ends, the whole whiteboard gets erased. Fresh start.

The Problem: Memory leaks

The term "Memory leak" is misleading.

The memory usually isn’t leaking out of the computer. A leak means resources remain allocated or objects remain reachable even though the application no longer needs them, so that memory cannot be reclaimed for future useful work.

In manually managed languages, code may forget to release an allocation. In garbage-collected languages, the collector can only free objects that are no longer reachable—so accidentally keeping a reference can retain an entire object graph.

“But my language has garbage collection 🤓 👆 “

Garbage collection (gc) does handle a lot of the cleanup work for you!

Usually…

However you can still leak memory by keeping references (hoarding):

all_results = []

def analyze_data(filename):
    huge_data = load_file(filename)  # Pretend it's 500MB
    result = process(huge_data)      
    all_results.append(huge_data)    # Why keep this?
    return result
# We never remove the data from all_results...

Each file keeps another huge object reachable through all_results. If the application never needs those inputs again and the list grows without bound, that’s a classic retention leak / unbounded retention.

The garbage collector cannot reclaim the objects because the global list still points to them. From the runtime’s perspective, they are still live.

Your program is now a digital hoarder, keeping everything "just in case."

Common Memory Leak Patterns

The Unbounded Cache (Java example):

class Cache {
    private final Map cache = new HashMap<>();

    void put(String key, Data value) {
        cache.put(key, value); // No size limit, TTL, or eviction policy.
    }
}

A cache is not automatically a leak. It becomes a memory problem when retention is unbounded relative to the workload. Real caches need some combination of size limits, TTLs, eviction, weak references, or explicit invalidation depending on the use case.

The Forgetter:

void processFile() {
    char* buffer = malloc(1000000);
    // We forgot to free(buffer)!
}

The Reachability Trap:

callbacks = []

class Screen:
    def __init__(self, name):
        self.name = name

    def on_event(self):
        print(self.name)

screen = Screen("settings")
callbacks.append(screen.on_event)

# Later the UI "closes" the screen...
screen = None

# ...but callbacks still holds a bound method, which keeps the Screen alive.

Circular references by themselves are not automatically leaks. Modern tracing garbage collectors such as Python’s can collect many unreachable cycles. The important question is whether something that is still reachable—like a global registry, listener, timer, cache, closure, or native handle—keeps data alive longer than intended.

Common fixes to memory leaks

1. Release resources deterministically

# Context managers guarantee the file handle is closed.
with open("file.txt", encoding="utf-8") as f:
    data = f.read()

File handles, sockets, locks, database connections, GPU buffers, and other OS/native resources are not the same thing as managed heap memory, but leaking them can be just as destructive. Use language/runtime cleanup mechanisms such as context managers, defer, RAII, finally, or explicit close/free APIs.

2. Bound caches and collections

from collections import OrderedDict

class LRUCache:
    def __init__(self, max_size=1000):
        self.max_size = max_size
        self.data = OrderedDict()

    def put(self, key, value):
        if key in self.data:
            self.data.move_to_end(key)
        self.data[key] = value

        if len(self.data) > self.max_size:
            self.data.popitem(last=False)

Production code will usually use a maintained cache implementation, but the principle is the important part: define how much can be retained and when it leaves.

3. Pair manual allocations with ownership

char* buffer = malloc(1000);
if (buffer == NULL) {
    /* handle allocation failure */
}

/* use buffer */

free(buffer);
buffer = NULL;  /* avoids accidentally reusing this pointer variable */

Setting this local pointer to NULL does not free anything by itself—the free() call does. In C/C++, clear ownership rules and RAII/smart pointers where appropriate reduce mismatched allocation/free paths.

4. Unsubscribe listeners and cancel long-lived work

const timer = setInterval(check, 1000);
const handler = () => refresh();
window.addEventListener('resize', handler);

// When the component/job is disposed:
clearInterval(timer);
window.removeEventListener('resize', handler);

Timers/listeners can retain closures and object references. Whether that becomes a leak depends on lifecycle: a timer intentionally running for the entire process is fine; one accidentally created on every screen mount and never removed is not.

Why Should You Care?

A leak in a short-lived process may never become noticeable because the operating system reclaims the process’s resources when it exits. In long-running services, games, desktop apps, workers, and embedded systems, retention bugs have time to accumulate.

But in long-running programs (servers, games, desktop apps, embedded systems), those leaks add up:

  • Game starts at 60 FPS, drops to 15 FPS after 2 hours

  • Server crashes every few days

  • Your Arduino project “mysteriously” stops working

  • Desktop app using 8GB of RAM for no reason

How to Spot a Leak

Possible symptoms:

  • The live heap / retained-object count grows after repeating the same workload.

  • Memory does not stabilize after traffic/workload returns to a previous level.

  • Garbage collection becomes more frequent/expensive.

  • The process eventually hits a memory limit, swaps heavily, or is killed.

Do not assume “RSS went up and did not immediately go down” proves a leak. Runtimes and allocators often keep freed pages for reuse instead of returning them to the OS. Compare heap/allocation snapshots and retained objects across repeated, representative workloads.

Helpful Tools

  • System metrics: Task Manager / Activity Monitor / container metrics for a quick trend—not proof by itself.

  • Python: built-in tracemalloc for allocation snapshots; tools such as Memray for deeper profiling.

  • JavaScript: browser/Node heap snapshots and allocation profiles.

  • Java: heap dumps, Java Flight Recorder, JDK Mission Control, VisualVM.

  • C/C++: Valgrind, AddressSanitizer/LeakSanitizer, platform heap profilers.

The Bottom Line

A useful mental model is: a memory leak is memory/resources kept alive longer than intended, with no bounded lifecycle. The cause might be a missing free(), a global reference, an unbounded cache, a forgotten listener, a native handle, or another ownership/lifecycle bug.

Watch out for:

  • Collections/caches with no bounds or eviction

  • Global registries and callbacks that retain dead objects

  • Forgotten native resources such as files/sockets/connections

  • Listeners, observers, subscriptions, and timers not removed with their owner

  • Manual allocations whose ownership/free path is unclear

Garbage collection prevents many manual-memory bugs, but it cannot know that a reachable object is logically useless to your application.

So don’t ask only “did I allocate memory?” Ask: what owns this object/resource, how long should it live, and what event releases it?

If you want to keep learning

  • Code profiling explained — use memory profilers to find which allocations keep growing and where the leak actually starts.

  • Debugging techniques — reproduce and isolate the behavior before changing random parts of your code.

  • Big O notation explained — understand the difference between code that scales badly by design and code that is leaking resources over time.

Thanks for the feedback!

Introducing Perplexity Labs

Perplexity Labs are a way to bring your projects to life faster than ever before

Introducing Zod 4 | Zod

After a year of active development: Zod 4 is now stable! It's faster, slimmer, more tsc-efficient, and implements some long-requested features.

Sign in with ChatGPT interest form

OpenAI is exploring ways for users to sign into third-party apps using their ChatGPT accounts. This interest form lets developers nominate their app for inclusion in a potential pilot.

My AI Skeptic Friends Are All Nuts

My smartest friends have bananas arguments about LLM coding.

Getting a Cease and Desist from Waffle House | Jack's Blog

Bit of a sticky situation.

Thanks to everyone who submitted!

andregarcia0412, bakzkndd, Kauketz, xanerin, jw123450, LaurelineP, mau-estradiote, SabhyaAggarwal, ariatheroyal, Sorbojit1, vmillios, and RelyingEarth87.


Next in the Alphabet

Create a function which returns the next letters alphabetically in a given string. If the last letter is a "Z", change the rest of the letters accordingly.

Examples

next_letters("A")
output = "B"
// 'A' becomes 'B' – simple increment.

next_letters("ABC")
output = "ABD"
// 'C' becomes 'D' – last character changes without carry.

next_letters("Z")
output = "AA"
// 'Z' rolls over to 'A', and since there's no previous letter, we add a new 'A'.
// Think of it like 9 + 1 = 10, here Z + 1 = AA.

next_letters("CAZ")
output = "CBA"
// 'Z' → 'A' (carry), 'A' → 'B' (no carry), so "CAZ" becomes "CBA".
// Like incrementing 129 → 130 but in letters.

next_letters("")
output = "A"
// Empty input is treated as 0 → return 'A'.

Notes

  • Tests will all be in CAPITALS.

  • Empty inputs should return a capital "A" (as if it were in letter position 0!).

  • Think about the letter "Z" like the number 9 and how it carries over to increment the next letter/digit over.

How To Submit Answers

Reply with

  • A link to your solution (github, twitter, personal blog, portfolio, replit, etc)

  • or if you’re on the web version leave a comment!

  • If you want to be mentioned here, I’d prefer if you sent a GitHub link or Replit!

New video this week hopefully!

Recently hired an editor, so I’m hoping I can start uploading consistently 😃

That’s all from me!

Have a great week, be safe, make good choices, and have fun coding.

If I made a mistake or you have any questions, feel free to comment below or reply to the email!

See you all next week.

What'd you think of today's email?

  • 🦥 Amazing! Keep it up
  • 🦥 Good, not great
  • 🦥 It sucked

Login or Subscribe to participate

Want to advertise in Sloth Bytes?

If your company is interested in reaching an audience of developers and programming enthusiasts, you may want to advertise with us here.

Keep Reading

Read all
arrow-right
envelope-simple

Join 50k+ developers and become a better programmer and stay up to date in just 5 minutes.

© 2026 Sloth Bytes.
beehiivPowered by beehiiv