Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
346 views
in Technique[技术] by (71.8m points)

iphone - Watching memory usage in iOS

Is there any way to find out how much memory is available in iOS? I know that the system will pass low memory warnings when available memory gets low. However, my App has some points where a single thread will perform a complex task and sometimes that task uses up enough memory that it is just terminated by the OS (my app can download pictures from the internet, and I scale them down to a small size ... if the user downloads a very large image, my app runs out of memory and just goes 'poof').

Having the App spontaneously terminate is obviously a poor user experience.

Is there any way that I can find out when I am about to run out of memory and stop the task instead?

I suppose I could put the task on a separate thread, and maybe the system would send the main thread a low memory warning, but that seems pretty complicated and not even guaranteed to work.

Thanks! Ron

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

While testing and debugging your app with XCode you can use this logMemUsage() function to NSLog the used/free space and watch how things are going while you test your app. This function logs any change in usage > 100kb. It outputs to the debug log like this (on the simulator the free space is huge):

2011-11-02 21:55:58.928 hello[971:207] Memory used 21884.9 (+21885), free 1838366.8 kb
2011-11-02 21:55:59.936 hello[971:207] Memory used 28512.3 (+6627), free 1830809.6 kb
2011-11-02 21:56:01.936 hello[971:207] Memory used 28803.1 ( +291), free 1830129.6 kb
2011-11-02 21:56:02.936 hello[971:207] Memory used 29712.4 ( +909), free 1830142.0 kb

You decide where to call logMemUsage in your app. I happen to have a function that is called by a timer every second and so I put it in there. I suggest using #ifdef around these so this code is only included in Debug builds.

#import "mach/mach.h" 

vm_size_t usedMemory(void) {
    struct 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);
    return (kerr == KERN_SUCCESS) ? info.resident_size : 0; // size in bytes
}

vm_size_t freeMemory(void) {
    mach_port_t host_port = mach_host_self();
    mach_msg_type_number_t host_size = sizeof(vm_statistics_data_t) / sizeof(integer_t);
    vm_size_t pagesize;
    vm_statistics_data_t vm_stat;

    host_page_size(host_port, &pagesize);
    (void) host_statistics(host_port, HOST_VM_INFO, (host_info_t)&vm_stat, &host_size);
    return vm_stat.free_count * pagesize;
}

void logMemUsage(void) {
    // compute memory usage and log if different by >= 100k
    static long prevMemUsage = 0;
    long curMemUsage = usedMemory();
    long memUsageDiff = curMemUsage - prevMemUsage;

    if (memUsageDiff > 100000 || memUsageDiff < -100000) {
        prevMemUsage = curMemUsage;
        NSLog(@"Memory used %7.1f (%+5.0f), free %7.1f kb", curMemUsage/1000.0f, memUsageDiff/1000.0f, freeMemory()/1000.0f);
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...