Here's an example of a pathological - but entirely reasonable to encounter - case:
You allocate several textures of various sizes. Your larger 3MB texture blocks might end up seperated by smaller allocations for, say, icons. Or other 3MB textures that can be reused on the next level (to reduce load times). Long story short, unless you do work to ensure textures are correctly grouped by lifetime (which in many cases will depend on and diverge based on user input) you're going to end up with lots of 3MB holes.
You switch levels, and release many/most of your 3MB environment textures. But the icons remain loaded for your UI, so you don't free those. So now you have 3MB holes everywhere.
You start to load the next level. It's using a lot more alpha textures in it's environment - lots of water and glass. The alpha channels adds another 33% to the size - these new textures are mostly 4MB. None of these new textures fit into the 3MB holes. You've already potentially just wasted about half your available memory (or address space), with a single texture size in two formats of note. Within a single system ("render"). Oops.
Untrue I'm afraid - the case I'm basing this example off of could (and did) happen in virtual address space as well.
> since you could mash the available fragmented phsyical ram together into whatever size blocks were needed using the MMU.
Okay, so your physical memory is no longer fragmented. Unfortunately, your virtual address space still is. If I need to allocate a 3MB contiguous chunk of virtual address space (I do), I'm still SOL.
All the MMU gains you in this respect is a "free" memcpy - twiddle some MMU bits instead of copying data around from one buffer to another. It won't fix up any of your pointers.
This is also why I suspect that they were mapping their virtual address space using block translation instead of a page table - if they had a page table, even in one process, it shouldn't have been a big issue since the virtual address space is many times larger than the available physical ram on the 360/PS3/Wii. The other possibility is that much of their RAM needs to be accessible by the GPU, for which fragmentation is an issue.
2GB of which is reserved for kernel shenanigans unless everyone enabled /3GB in their kernel boot parameters (they haven't.)
Default allocators start failing at around half that amount.
Meanwhile I'm running out of memory on the new generation of consoles where I have 5GB of physical memory and no virtual memory fragmentation to worry about.