Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Where is my iPad runtime memory going?

I'm causing the device (iPad) to run out of memory apparently, so it is jettisoning my app. I'm trying to understand what is going on as Instruments is telling me that I'm using about 80Mb, and there is no other app running on the device.

I found this code snippet to ask the Mach system under iOS for the memory stats:

#import <mach/mach.h>
#import <mach/mach_host.h>

static void print_free_memory () {
mach_port_t host_port;
mach_msg_type_number_t host_size;
vm_size_t pagesize;

host_port = mach_host_self();
host_size = sizeof(vm_statistics_data_t) / sizeof(integer_t);
host_page_size(host_port, &pagesize);       

vm_statistics_data_t vm_stat;

if (host_statistics(host_port, HOST_VM_INFO, (host_info_t)&vm_stat, &host_size) != KERN_SUCCESS)
    NSLog(@"Failed to fetch vm statistics");

/* Stats in bytes */
natural_t mem_used = (vm_stat.active_count +
                      vm_stat.inactive_count +
                      vm_stat.wire_count) * pagesize;
natural_t mem_free = vm_stat.free_count * pagesize;
natural_t mem_total = mem_used + mem_free;
NSLog(@"used: %u free: %u total: %u", mem_used, mem_free, mem_total);
}

When I use this function to obtain the three memory values, I am finding that the mem_total value is going way down even though the mem_used total is not changing all that much. Here are two successive output lines:

<Warning>: used: 78585856 free: 157941760 total: 236527616

some code executes....

<Warning>: used 83976192 free: 10551296 total: 94527488

So all of a suden I go from 157MB of free memory to 10MB of free memory, but my usage only increased from 78MB to 84MB. The total memory decreased from 236MB to 94MB.

Does this make sense to anybody? There are no other applications running on the device during this time period, the device should be basically totally dedicated to my application.

All of the code that executes between the two memory checks is native C++ code that has no interaction at all with any Apple framework. There are indeed many, many calls to the memory system to allocate and deallocate objects from the C++ heap, but as seen, only about 4MB of additional memory is in the end allocated, all the rest is freed / deleted.

Can it be that the missing memory is being consumed by heap fragmentation? I.e. is the heap simply so fragmented that the block overhead is consuming all of the additional, unaccounted, memory?

Has anyone else seen this behavior?

Thanks,

-Eric

like image 432
Eric Avatar asked Mar 03 '11 15:03

Eric


1 Answers

You should use task_info instead of host_statistics to retrieve memory usage of your application:

# include <mach/mach.h>
# include <mach/mach_host.h>

void dump_memory_usage() {
  task_basic_info info;
  mach_msg_type_number_t size = sizeof( info );
  kern_return_t kerr = task_info( mach_task_self(), TASK_BASIC_INFO, (task_info_t)&info, &size );
  if ( kerr == KERN_SUCCESS ) {
    NSLog( @"task_info: 0x%08lx 0x%08lx\n", info.virtual_size, info.resident_size );
  }
  else {
    NSLog( @"task_info failed with error %ld ( 0x%08lx ), '%s'\n", kerr, kerr, mach_error_string( kerr ) );
  }
}
like image 188
Andrey Starodubtsev Avatar answered Oct 03 '22 04:10

Andrey Starodubtsev