Viendo el uso de la memoria en iOS

¿Hay alguna manera de averiguar cuánta memoria hay disponible en iOS? Sé que el sistema pasará advertencias de memoria baja cuando la memoria disponible se agota. Sin embargo, mi aplicación tiene algunos puntos en los que un único subproceso llevará a cabo una tarea compleja y, a veces, esa tarea consume suficiente memoria como para que el sistema operativo la finalice (mi aplicación puede descargar imágenes de Internet y reducirlas a una pequeña tamaño … si el usuario descarga una imagen muy grande, mi aplicación se queda sin memoria y acaba diciendo ‘poof’).

Tener la aplicación de forma espontánea terminar es obviamente una experiencia de usuario pobre.

¿Hay alguna manera de que pueda averiguar cuándo estoy a punto de quedarme sin memoria y detener la tarea?

Supongo que podría poner la tarea en un hilo separado, y tal vez el sistema envíe al hilo principal una advertencia de poca memoria, pero parece bastante complicado y ni siquiera garantiza que funcione.

¡Gracias! Ron

Al probar y depurar su aplicación con XCode, puede usar esta función logMemUsage() para NSLogar el espacio usado / libre y observar cómo van las cosas mientras prueba su aplicación. Esta función registra cualquier cambio en el uso> 100kb. Sale al registro de depuración de esta manera (en el simulador, el espacio libre es enorme):

 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 

Usted decide dónde llamar a logMemUsage en su aplicación. Tengo una función llamada por temporizador cada segundo y la pongo allí. Sugiero usar #ifdef alrededor de estos, por lo que este código solo se incluye en comstackciones de depuración.

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

En realidad, cada controlador de vista tiene funciones - (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. } 

Como sugieren los comentarios, puede publicar datos no utilizados en el comentario. Por otro lado, comente [super didReceiveMemoryWarning]; para suprimir las advertencias de memoria y los objetos de liberación automática.

Primero, el título de su pregunta es cómo ver el uso de la memoria en iOS. Hay una herramienta llamada instrumento que viene con xcode, que puede usar para rastrear la asignación de memoria, fugas, uso de la CPU y una serie de otras cosas. Consulte la documentación de Apple sobre el tema..

  • Ahora, para ver el uso de la memoria en tiempo real de su aplicación, puede usar la herramienta de asignación en el instrumento
  • Para identificar las pérdidas de memoria, puede usar la herramienta de fugas en el instrumento.

También en WWDC 2010 hay un video de cómo analizar la memoria usando el Instrumento.

Recomiendo ver la herramienta de descripción general de Nimbus para ver las estadísticas del dispositivo en tiempo real. De fábrica, incluye páginas para ver la memoria disponible, el espacio en disco y los registros, así como la modificación de los niveles de registro. También es fácil agregar páginas personalizadas que muestran la información que desea.

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

Herramienta de descripción general de Nimbus

El conjunto de herramientas de desarrollo que ofrece Apple incluye “Instrumentos”. Puede usar esto para monitorear las asignaciones y fugas. En Xcode, si haces clic largo en el botón Ejecutar, verás una opción llamada “Perfil”. Esto abrirá los instrumentos automáticamente y le permitirá seleccionar un perfil para monitorear su aplicación.

Me encanta el código libre. Gracias progrmr, muy útil. Es hora de que comience a compartir de nuevo. Lo orienté objetivamente para mi propio caso de uso.

 #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 

Parece que podría usar una biblioteca bien diseñada para la tarea de buscar imágenes web. Nimbus tiene una clase de imagen de red que lo hace de manera eficiente .