Desarrollo de iOS: ¿Cómo puedo inducir advertencias de poca memoria en el dispositivo?

91

Me gustaría probar que mi aplicación funciona bien en condiciones de poca memoria, pero es difícil de probar. ¿Cómo puedo inducir advertencias de memoria baja que activen el método didReceiveMemoryWarning en mis vistas cuando la aplicación se está ejecutando en el dispositivo, no en el simulador? ¿O de qué formas puedo probar mi aplicación en estas posibles condiciones?

La razón por la que no puedo usar el simulador es que mi aplicación usa Game Center y las invitaciones no funcionan en el simulador.

BeachRunnerFred
fuente

Respuestas:

8

Para probar en un dispositivo, simplemente agregue un código que asigne periódicamente grandes cantidades de memoria sin liberarla (es decir, que se filtre a propósito). Puede hacer esto en un hilo separado, o en respuesta a un temporizador, o usando el mecanismo que mejor le permita probar y observar el comportamiento de su aplicación.

También puede optar por crear una aplicación separada que haga algo similar y esté diseñada para ejecutarse en segundo plano, si desea reutilizarla fácilmente y / o probarla con varias aplicaciones.

Estrella binaria
fuente
7
no muy practico. la solución para llamar a un método privado para realizar pruebas es mejor
Daij-Djan
4
No es una buena solución si desea ver un escenario del mundo real. Estás paralizando la aplicación debido a una fuga que no se debe a la presión de la memoria. Eso es malo, ya que lo que quieres hacer es probar cómo responde la aplicación en un estado de alta presión de memoria. En el lado negativo, es más difícil averiguar cuál es el problema: una fuga real o la falsa que introdujiste. El método privado uno es mejor para probar como se indica a continuación.
fzaziz
2
Esta respuesta no debe ser rechazada, ya que el segundo párrafo es en realidad lo que Apple dice que haga si desea probar el comportamiento de su aplicación cuando la memoria realmente se agota.
Matt
1
¡La respuesta se mejoraría con un bloque de código para realizar esta asignación!
pkamb
Aunque la configuración requiere más trabajo, esta es una prueba más realista que llamar al método privado. Cuando realmente exista una presión crítica de memoria, ¿podrá su aplicación realizar las acciones que le indique? ¿Y esas acciones aliviarán la situación o la empeorarán y harán que iOS la termine? Además, el método privado no funciona para probar DISPATCH_SOURCE_TYPE_MEMORYPRESSURE.
jk7
278

Puede llamar al método privado :

[[UIApplication sharedApplication] performSelector:@selector(_performMemoryWarning)];

Solo recuerde usarlo solo en depuración, o su aplicación será rechazada.

Enzo Tran
fuente
6
Parece que este código simula con precisión la advertencia de memoria en el dispositivo. ¡Gracias Enzo!
William Denniss
28
En lugar de usar esto en el código, ejecútelo en el depurador. Simplemente po [[UIApplication sharedApplication]performSelector:@selector(_performMemoryWarning)]
presione
17
En lugar de usar po, use expr, es decirexpr (void)[[UIApplication sharedApplication] performSelector:@selector(_performMemoryWarning)];
Andy
11
En el depurador, no es necesario utilizar la solución alternativa para no tener el encabezado:expr (void)[[UIApplication sharedApplication] _performMemoryWarning]
OrangeDog
3
Para cualquiera que esté buscando hacer esto con Swift: escriba en expr UIApplication.sharedApplication().performSelector("_performMemoryWarning")lugar de usar el habitual#selector
funct7
27

El Simulate Memory Warningelemento de menú del simulador de iOS le permite simular una advertencia de memoria.

Ole Begemann
fuente
La única forma de verificarlo en el dispositivo es forzarlo, es decir, usando la aplicación durante largos períodos de tiempo o imágenes intensivas o lo que sea, variará de una aplicación a otra. Una sugerencia podría ser usar un dispositivo más antiguo (¿3g quizás?) En lugar de un iPhone 4 para ayudarlo a llegar a la advertencia más rápido.
Jesse Naugher
Gracias, Jesse, creo que solo voy a agregar algunos trucos a mi aplicación para simular invitaciones para que pueda ejecutarla en el simulador e inducir las advertencias de memoria de esa manera.
BeachRunnerFred
10
La pregunta fue sobre la simulación en el dispositivo.
KPM
20

Usando Instrumentos, use el elemento de menú: Instrumento -> Simular advertencia de memoria.

Para usar Instruments en su aplicación desde Xcode, use el elemento de menú Producto -> Perfil.

ThomasW
fuente
Esto es incluso mejor.
Zappel
@OrangeDog ¿Qué está pasando?
ThomasW
2
Pues nada. Cuando uso las vistas de respuesta de Enzo, tengo que volver a cargarlas cuando vuelvo a ellas, no así con este método.
OrangeDog
12

He reescrito la respuesta de Enzo Tran en Swift:

UIControl().sendAction(Selector(("_performMemoryWarning")), to: UIApplication.shared, for: nil)
ChikabuZ
fuente
¡Gracias! Xcode advierte de "ningún método declarado con el selector Objective-C", pero esto funciona de todos modos.
man1
10

Si alguien, por cualquier motivo, intenta hacer esto en Swift 4, aquí se explica cómo asignar 1.2 GB de RAM.

let d = Data.init(repeating: 100, count: 1200000000)
  • Esto es útil para activar una alerta de advertencia en otras aplicaciones.
Adobels
fuente
¿Hacer algo como esto ofuscará la información de la memoria real que estoy tratando de ver en Instrumentos? Si bien veo que no hay una forma adecuada de hacer esto en un dispositivo físico, si mi punto es ver qué está ocupando mi memoria dentro de mi aplicación, parece que esto va a sesgar todos los datos y no ya tiene una respuesta relativa. Seguiré viendo lo que está ocupando más , pero no las verdaderas proporciones.
Jake T.
esto se bloquea inmediatamente
Daniel Springer
7

Hay un comando de menú que lo invocará.

Hardware > Simulate Memory Warning desde el simulador.

Daniel A. White
fuente
8
La pregunta fue sobre la simulación en el dispositivo.
KPM
2
En Xcode 10 ahora está en Depurar> Simular advertencia de memoria.
Sebbo
7

Convirtió @ChikabuZ en Swift 3:

UIControl().sendAction(Selector(("_performMemoryWarning")), to: UIApplication.shared, for: nil)
un poco
fuente
4

Si alguien, por el motivo que sea, intenta hacer esto en Swift 3, aquí se explica cómo asignar 1,2 GB de RAM.

   for i in 0...1200 {
      var p: [UnsafeMutableRawPointer] = []
      var allocatedMB = 0
      p.append(malloc(1048576))
      memset(p[allocatedMB], 0, 1048576);
      allocatedMB += 1;
   }
ph1lb4
fuente
3
let d = Data.init (repitiendo: 100, recuento: 1200000000)
Adobels
2
@Adobels deberías publicar eso como respuesta :)
Koen.
1

Rápido 4:

UIApplication.shared.perform (Selector (("_ performMemoryWarning")))

Puede ejecutar lo anterior en respuesta a un evento / notificación.

Vishal Chaudhry
fuente