I am trying to use mmap to read and play audio files on iOS. It works great for files up to 400 MB in size. But when I try to create a 500 MB file, I get an ENOMEM error.
char *path = [[[NSBundle mainBundle] pathForResource: @"test500MB" ofType: @"wav"] cStringUsingEncoding: [NSString defaultCStringEncoding]]; FILE *f = fopen( path, "rb" ); fseek( f, 0, SEEK_END ); int len = (int)ftell( f ); fseek( f, 0, SEEK_SET ); void *raw = mmap( 0, len, PROT_READ, MAP_SHARED, fileno( f ), 0 ); if ( raw == MAP_FAILED ) { printf( "MAP_FAILED. errno=%d", errno );
Why?
I would be pleased with an answer like "700 MB is a virtual memory limitation, but sometimes the address space is fragmented, so you get 700 MB, but in smaller pieces." (This is just an assumption, I still need an answer)
The Apple virtual memory document page says:
Although OS X supports backup storage, iOS does not. In an iPhone application, read-only data that is already on disk (for example, page code) is simply deleted from memory and reloaded from disk as needed.
which seems to confirm that mmap should work on blocks larger than physical memory, but still doesn't explain why I push such a low limit.
Update
- This answer is interesting, but 500 MB is well below the 700 MB limit that he mentions.
- This discussion refers to continuous memory . So memory fragmentation can be a real problem?
- I am using the 4th generation iPod Touch with 256 MB physical memory.
- The goal of my research is to see if there is a better way to manage memory when loading read-only data from files than to "save the selection until you get a warning about the memory."
mmap seemed like a good way to solve this problem ...
Update 2
I expect mmap to work perfectly with the new 64-bit version of iOS. Will check as soon as I get my hands on a 64-bit device.
memory-management ios mmap
Tomas andrle
source share