MemoryError is raised when Python cannot allocate memory for an operation. Two very different situations produce it: data that is legitimately enormous, and a bug that grows memory without bound (an infinite loop appending to a list is the textbook case). Distinguishing them matters, because the first is solved by streaming and data types, and the second by finding the leak-like loop that no amount of RAM would satisfy.
seen = []
while True: # nothing ever stops this
seen.append(load_next_batch())
Traceback (most recent call last):
File "main.py", line 3, in <module>
MemoryError
# the honest fix is a stopping condition or streaming,
# not more RAM: process each batch and let it go
read() on the whole file; use generators so results are produced and discarded one at a time instead of collected into a list.list * n on big data, joining enormous strings in a loop, and keeping every intermediate result in a “history” list are quiet multipliers. Most “huge data” programs are holding the data three times over.If a program's memory grows in proportion to uptime rather than input size, something accumulates per operation (caches without eviction, registries of completed tasks, logging buffers). Profile by counting: print the lengths of the long-lived collections periodically and the growing one names itself.
Why didn't the operating system just kill the process? Sometimes it does (on Linux the OOM killer shoots before Python can raise). MemoryError appears when the allocator reports failure in an orderly way, common when a per-process or container limit is hit rather than the machine's total RAM.
Will adding RAM fix my MemoryError? Only if the workload's true peak is bounded and larger than the machine. For an unbounded-growth bug, more RAM delays the crash and makes it slower to reproduce; the growth curve tells you which case you are in.