5

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

Eric
  • 151
  • 1
  • 9
  • 1
    Eric, have you gotten an answer to this issue somewhere? I'm struggling with some similar problems, (but getting there in a very different way) and I'm wondering how IOS handles heap fragmentation. – Ethan Mar 31 '11 at 05:42
  • No, I never received a definitive answer to this, but poking around in other forums and other blog posts I find that that this technique for looking at memory is not really valid. That is the values returned don't necessarily tell you anything about your particular application, except in a general way. The trend of the numbers is important, but the particular values don't make a lot of sense, especially as the "total" number is so variable, though a priori one would think it should be fixed. – Eric May 06 '11 at 14:37

1 Answers1

10

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 ) );
  }
}
Andrey Starodubtsev
  • 4,588
  • 2
  • 24
  • 40
  • a while ago this but...running that code and comparing to the output of XCode's memory profile shows a fairly consistent mismatch of about 30megs (i.e. XCode shows ~30 Megs *less* used than the task info) - any idea why that might be..? – SonarJetLens Jun 10 '15 at 11:25
  • idk, but maybe (just a stab in the dark) XCode shows statistics related to heap allocations (via some hidden functions like `mallinfo`), and `task_info` returns amount of memory acquired by process via `mmap` which obviously can be larger. – Andrey Starodubtsev Jun 10 '15 at 13:21
  • that sounds reasonable; what I've seen so far is also that it at least isn't reporting *less* used memory used than XCode (which I'll assume is more accurate perhaps..) and together with the slightly lower total device memory reported by sysctl I still get a fairly good "memory pressure" % to display in my app for testing and monitoring... – SonarJetLens Jun 10 '15 at 13:55
  • Thx for pointing out task_info ; But can you help answer my related questions? https://stackoverflow.com/questions/47071265/how-to-analyze-stack-info-of-a-thread – Paradise Nov 02 '17 at 09:09