I did iOS 3D game dev back in the 2G days where you only got 24MB of RAM to work in if you were lucky. Even in the later device with lots more memory, the amount you could use before getting a memory warning was small and varied wildly depending on what the user had been doing recently before firing up your app.
One technique to handle this is mentioned in the article: We used read-only memory mapped files containing position-independent data structures. We did this for audio and animation data without notable hitches.
The big one though was making our meshes and textures hot-reloadable. Whenever we got a memory warning, we just deleted the OpenGL buffers for all of our meshes and textures and let them reload on-demand.
From the POV of the OS we were being a very well-behaved citizen. The OS asked us to reduce memory and we did so instantly and dramatically. Meanwhile, the OS was also issuing memory warnings to all of the background apps that were hogging large, unpredictable chunks of RAM. Those apps would end up killed by the OS in short order, freeing up memory for us.
Right each kill-wave, we would naturally get right back to filling RAM with even more meshes and textures, triggering another memory-warning with would free up even more mem for us!
Pretty quickly we'd have all of the memories and the warnings would slow down. Using PVRTC texture compression and tightly pack vertex formats meant we could have a lot of detail loaded. And, simple binary file formats with just `fread(whole file in one go)` as our I/O practice meant we could reload everything in 1/10th of a second.
Maybe more interestingly - that is the correct behaviour from the user's POV. The application that the user is currently interacting with is given more resources and background processes are throttled and killed until the user is done with their one task. Not sure what the takeaway here is - a well-behaved program deserves to be given more resources? Foreground applications should be the last ones killed?
It's interesting, because some of this memory management behavior is still visible now. You can tell which apps are light on resources by how many hours/days they manage to remain in memory without being killed, and it's not unusual to see memory hog apps kill each other in multitasking.
<guess>VM space is not free. You need pagetables and various other structures to support it. The larger the VM space, the more of them you need, which costs real actual RAM. ASLR would make it worse as it will scatter VM allocations around the address space more, forcing the creation of a lot more 1st and second stage pagetables (and possibly other structures)</guess>
> On 64-bit Apple platforms, the entire 4 GiB 32-bit address space (addresses [0x00000000, 0xFFFFFFFF]) is not accessible by the process, which catches both NULL pointer dereference bugs and 64-bit to 32-bit pointer truncation bugs.
Is that just an iOS thing, or does macOS do that as well? Anyone know?
17 comments
[ 0.20 ms ] story [ 45.2 ms ] threadOne technique to handle this is mentioned in the article: We used read-only memory mapped files containing position-independent data structures. We did this for audio and animation data without notable hitches.
The big one though was making our meshes and textures hot-reloadable. Whenever we got a memory warning, we just deleted the OpenGL buffers for all of our meshes and textures and let them reload on-demand.
From the POV of the OS we were being a very well-behaved citizen. The OS asked us to reduce memory and we did so instantly and dramatically. Meanwhile, the OS was also issuing memory warnings to all of the background apps that were hogging large, unpredictable chunks of RAM. Those apps would end up killed by the OS in short order, freeing up memory for us.
Right each kill-wave, we would naturally get right back to filling RAM with even more meshes and textures, triggering another memory-warning with would free up even more mem for us!
Pretty quickly we'd have all of the memories and the warnings would slow down. Using PVRTC texture compression and tightly pack vertex formats meant we could have a lot of detail loaded. And, simple binary file formats with just `fread(whole file in one go)` as our I/O practice meant we could reload everything in 1/10th of a second.
Is that just an iOS thing, or does macOS do that as well? Anyone know?