Подтвердить что ты не робот

Просмотр использования памяти в iOS

Есть ли способ узнать, сколько памяти доступно в iOS? Я знаю, что система будет передавать предупреждения с низкой памятью, когда доступная память станет низкой. Тем не менее, у моего приложения есть некоторые моменты, когда один поток выполняет сложную задачу, и иногда эта задача использует достаточное количество памяти, которое просто прекращается ОС (мое приложение может загружать изображения из Интернета, и я масштабирую их до небольшого размер... если пользователь загружает очень большое изображение, у моего приложения заканчивается память и просто идет "poof" ).

Наличие спонтанного завершения приложения, очевидно, является плохим пользовательским интерфейсом.

Есть ли способ, который я могу узнать, когда у меня закончится нехватка памяти и остановите задачу?

Я полагаю, что я мог бы поставить задачу на отдельный поток, и, возможно, система отправила основной поток предупреждение о низкой памяти, но это кажется довольно сложным и даже гарантированным не работает.

Спасибо! Рон

4b9b3361

Ответ 1

Во время тестирования и отладки вашего приложения с помощью XCode вы можете использовать эту функцию logMemUsage() для NSLog используемого/свободного места и следить за тем, как все происходит во время тестирования вашего приложения. Эта функция регистрирует любые изменения в использовании > 100 кб. Он выводится в журнал отладки, как это (на симуляторе свободное пространство огромно):

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

Вы решаете, где вызывать logMemUsage в своем приложении. У меня, случается, есть функция, вызываемая таймером каждую секунду, и поэтому я помещаю ее туда. Я предлагаю использовать #ifdef вокруг них, поэтому этот код включен только в сборки Debug.

#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);
    }
}

Ответ 2

Фактически каждый контроллер представления имеет - (void)didReceiveMemoryWarning функции.

- (void)didReceiveMemoryWarning
{
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];

    // Release any cached data, images, etc that aren't in use.
}

Как указано в комментариях, вы можете опубликовать неиспользуемые данные в комментарии. С другой стороны, закомментируйте [super didReceiveMemoryWarning]; для подавления предупреждений памяти и объектов автоматического выпуска.

Ответ 3

Во-первых, заголовок вашего вопроса - это то, как смотреть использование памяти в iOS. Существует инструмент, называемый инструментом, который поставляется с xcode, который вы можете использовать для отслеживания распределения памяти, утечек, использования процессора и множества других вещей. См. Apple documentation по этому вопросу..

  • Теперь, чтобы увидеть использование памяти в реальном времени вашего приложения, вы можете использовать инструмент распределителя в приборе
  • Чтобы идентифицировать утечки памяти, вы можете использовать инструмент утечки в инструменте.

Также в WWDC 2010 существует video, как анализировать память с помощью инструмента..

Ответ 4

Я рекомендую проверить инструмент обзора Nimbus для просмотра статистики устройств в режиме реального времени. Из коробки он включает страницы для просмотра доступной памяти, дискового пространства и журналов, а также изменения уровней журналов. Также легко добавлять пользовательские страницы, которые показывают любую информацию, которую вы хотите.

http://latest.docs.nimbuskit.info/NimbusOverview.html

Nimbus' Overview Tool

Ответ 5

Набор инструментов для разработки, которые Apple предоставляет, включает "Инструменты". Вы можете использовать это для мониторинга распределения и утечек. В Xcode, если вы долго нажимаете кнопку "Выполнить", вы увидите опцию "Профиль". Это автоматически откроет инструменты и позволит вам выбрать профиль для мониторинга вашего приложения.

Ответ 6

Я люблю бесплатный код. Спасибо прогрм, очень полезно. Пора мне начать делиться воспоминаниями. Я объектно ориентировал его для собственного использования.

#import "mach/mach.h"
#import "memusage.h"



@implementation memusage

static long prevMemUsage = 0;
static long curMemUsage = 0;
static long memUsageDiff = 0;
static long curFreeMem = 0;

-(vm_size_t) freeMemory {
    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;
}

-(vm_size_t) usedMemory {
    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
}

-(void) captureMemUsage {
    prevMemUsage = curMemUsage;
    curMemUsage = [self usedMemory];
    memUsageDiff = curMemUsage - prevMemUsage;
    curFreeMem = [self freeMemory];


}

-(NSString*) captureMemUsageGetString{
    return [self captureMemUsageGetString: @"Memory used %7.1f (%+5.0f), free %7.1f kb"];
}

-(NSString*) captureMemUsageGetString:(NSString*) formatstring {
    [self captureMemUsage];
     return [NSString stringWithFormat:formatstring,curMemUsage/1000.0f, memUsageDiff/1000.0f, curFreeMem/1000.0f];

}

@end