I’ve been working in games since before then, and it’s a common trick. It’s often portrayed as if it would occur because of poor memory management (I.e. memory not being freed), but even with perfect memory management it can happen in constrained memory environments (like consoles).<p>What happens is you would are allocating large memory chunks at level loading time, and potentially a number of smaller allocations during the a user playing that need to be persistent (for example, player save data). You would inevitably end up with a small block of memory allocated in the middle of a large free chunk, and would unable to allocate a large chunk that spanned the small allocated chunk. This was manageable up to point, you would try and pre allocate as much of the persistent memory as possible so that it would end up at similar addresses and contiguous, but it was difficult to guarantee.<p>Theoretically, of course, you can develop without allocating persistent memory in game, but it becomes difficult to maintain, and limits you in other areas. If you used any 3rd party libraries that allocated memory, or certain template functions or standard library functions that allocated memory, you had to work around that. If your game wasn’t linear and players can move around dynamically, this becomes exponentially difficult.<p>On consoles, we also had to pass “soak” tests, where the game has to run in a demo mode for 24-48 hours or longer, continuously without crashing or errors.<p>Inevitably the only solution was to force all your memory to get remapped, but the only way to do that was to reallocate everything in a relatively predictable order, and the only way to do that was to save your state, force a reboot, and reload. Hence the “hack”, except that this was so common, facilities existed that helped you do it. Normally, there was a chunk of memory that persisted between soft reboots, so you could store your state here. You could also pass flags to the rebooted executable, to tell it where or how to load.