A great analogy is shopping carts at a grocery store. You come into the store, pick up a cart, use it, and when you’re done you put it into a corral, signifying that you are done. Periodically a worker will collect carts from the corrals and return them to the store.
Now imagine someone shows up, takes a cart, and doesn’t return it when they’re done. They’re on foot or something so they just walk back home with the cart and leave it on the street in front of their house when they’re done, so the cart worker never notices it as an available cart. They do this a couple of times, and nobody really notices. But if they’re doing this twice a week for a year, suddenly you’re missing 100 shopping carts and there aren’t enough left in circulation to go around and people start getting frustrated when they walk into your store and can’t find a cart.
Getting a shopping cart is memory allocation. Putting it in the corral is releasing allocated memory. Cart workers are “garbage collection” that recycles released memory into circulation. The person taking the carts and not returning them is a memory leak.
Now how does this actually happen? Many higher level languages have automatic garbage collection, so it’s rare to get a leak because allocated memory doesn’t get manually released. But lower level languages require explicit manual release to trigger garbage collection. In C, for instance, memory allocation is all very explicit and manual, you have to carve out the memory you want exactly when an object is instantiated, and you use a pointer variable to indicate the address in memory that you allocated. If you later point that pointer to a different address without de-allocating the initial object, then you no longer have a way to track where that allocated memory actually is in order to tell the garbage collector when you are done with it, and the memory manager will still hold that space indefinitely until the entire program is terminated. But even in higher level languages you can run into issues if you are repeatedly declaring new variables without ever letting go of your old ones. If you have, say, a map that counts every word someone types in chat, and you continually add new words to it as you see them, and never clear that map out or close the program, eventually it can get large enough that it’ll be consuming all available memory and the program will crash. This would be like if a customer walks into the store and keeps getting more and more carts, putting a few items in each, with the intent of buying them all, but never actually checks out.
Latest Answers