Memory and garbage collection
Back to the title screen
A player in a co-op garden switches to a chat app for a minute. When they come back, Shard Garden restarts from the title screen. Their garden is gone.
Quick reminder: the garbage collector frees memory nothing points to any more, and a memory leak is memory the game holds but never uses again. Today: how the collector works, and what a phone does when memory runs out.
Most objects die young
V8, the JavaScript engine in Chrome, builds its garbage collector on one observation: most objects die young. A spark, a temporary vector, a path step: made, used, forgotten within a frame.
So the heap is split in two. The young generation is cleaned often by a quick minor GC, the Scavenger. Survivors move to the old generation, which a major GC, Mark-Compact, cleans across the whole heap. V8's team says reducing these pauses still matters.
Quick check
V8's garbage collector is designed around the idea that most objects become garbage soon after they are made.
- True
- False
Show the answer
True
That is the generational idea: "most objects die young". It is why the young generation gets a quick, frequent cleanup of its own.
Shallow size and retained size
A heap snapshot lists every object with two sizes:
- Shallow size: the memory the object itself holds.
- Retained size: the memory that would be freed if the object was deleted, together with everything only it keeps alive.
A 64-byte object can retain 58 MB if it points to a list of old level copies. Sort by retained size to find what is really holding memory.
Read the snapshot
1Object Shallow Retained2GardenTile 96 B 3.1 KB3UndoHistory 64 B 58.0 MB4Pest 120 B 1.4 KB
Which object should Remy look at first?
- UndoHistory
- Pest
- GardenTile
Show the answer
UndoHistory
UndoHistory is tiny itself but keeps 58 MB alive: the level editor's undo history holds a full copy of the level for every edit.
What a phone does when memory runs out
On Android, the CPU and GPU access the same RAM, so textures and JavaScript share one pool. When it runs low, Android first calls onTrimMemory() to ask apps to free some.
If that isn't enough, the low-memory killer ends processes. Each has a score, and the highest goes first: background apps first, system processes last. When the foreground app is killed, it looks like a crash to the player.
Quick check
Why did Shard Garden restart after the player checked a chat message?
- While it was in the background, the low-memory killer ended it to free memory
- The garbage collector deleted the save file
- The Cache-Control header expired
Show the answer
While it was in the background, the low-memory killer ended it to free memory
Background apps are the first to be killed when memory runs low. A game using lots of memory is a bigger target, and anything it hadn't saved is lost.
Use less, and save before you go
- Save when hiddenOn the web, the visibilitychange event says the page is hidden. Save the garden then, before the phone can end the game.
- Only the textures in useKeep the current shard's textures loaded and free the others.
- Cap the historyRemy keeps the last 50 undo steps, not every edit since the morning.
Quick check
Limiting the editor's undo history to the last 50 edits lowers the retained size of UndoHistory.
- True
- False
Show the answer
True
Old level copies beyond the last 50 are no longer reachable from UndoHistory, so the garbage collector can free them, and the retained size drops.
Memory is not the only limit
Even a game with no leaks and a perfect frame budget slows down after 20 minutes on a real phone.
Bolt says: Next: heat and battery, the limit you only find by playing for a long time.
Fact-checked 11 October 2026
- V8: Trash talk, the Orinoco garbage collector v8.dev
- Chrome DevTools: Memory terminology developer.chrome.com
- Android Developers: Memory allocation among processes developer.android.com
- MDN: Page Visibility API developer.mozilla.org