Desenvolvimento iOS: Como posso induzir avisos de pouca memória no dispositivo?


91

Gostaria de testar as funções do meu aplicativo bem em condições de pouca memória, mas é difícil de testar. Como posso induzir avisos de pouca memória que acionam o método didReceiveMemoryWarning em minhas visualizações quando o aplicativo está sendo executado no dispositivo, não no simulador? Ou de que maneiras posso testar meu aplicativo nessas condições possíveis?

Não consigo usar o simulador porque meu aplicativo usa o Game Center e os convites não funcionam no simulador.

Respostas:


8

Para testar em um dispositivo, basta adicionar algum código que aloca periodicamente grandes blocos de memória sem liberá-la (ou seja, vazamento proposital). Você pode fazer isso em um thread separado, ou em resposta a um cronômetro, ou usando qualquer mecanismo que melhor permita testar e observar o comportamento de seu aplicativo.

Você também pode optar por criar um aplicativo separado que faça algo semelhante e seja projetado para ser executado em segundo plano, se quiser reutilizá-lo facilmente e / ou testar com vários aplicativos.


7
não é muito prático. a solução para chamar um método privado para teste é melhor
Daij-Djan

4
Não é uma boa solução se você deseja observar o cenário do mundo real. Você está paralisando o aplicativo devido a um vazamento, não devido à pressão da memória. Isso é ruim, pois o que você quer fazer é testar como o aplicativo responde em estado de alta pressão de memória. No lado negativo, é mais difícil descobrir qual é o problema: um vazamento real ou falso que você introduziu. O método privado é melhor para testar conforme mostrado abaixo.
fzaziz de

2
Esta resposta não deve ser rejeitada, pois o segundo parágrafo é realmente o que a Apple diz para fazer se você quiser testar o comportamento do seu aplicativo quando a memória realmente ficar baixa.
matt

1
A resposta seria melhorada com um bloco de código para realizar essa alocação!
pkamb

Embora exija mais trabalho para configurar, este é um teste mais realista do que chamar o método privado. Quando realmente há pressão crítica de memória, seu aplicativo será capaz de realizar as ações que você ordenar? E essas ações irão aliviar a situação ou torná-la pior e fazer com que o iOS a encerre? Além disso, o método privado não funciona para testar DISPATCH_SOURCE_TYPE_MEMORYPRESSURE.
jk7

278

Você pode chamar o método privado :

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

Lembre-se de usá-lo apenas na depuração, ou então seu aplicativo será rejeitado.


6
Parece que este código simula com precisão o aviso de memória no dispositivo. Obrigado Enzo!
William Denniss

28
Em vez de usar isso no código, execute-o no depurador. Basta clicar em pausa e entrarpo [[UIApplication sharedApplication]performSelector:@selector(_performMemoryWarning)]
orkoden

17
Ao invés de usar po, expr utilização, isto é,expr (void)[[UIApplication sharedApplication] performSelector:@selector(_performMemoryWarning)];
Andy

11
No depurador, você não precisa usar a solução alternativa para não ter o cabeçalho:expr (void)[[UIApplication sharedApplication] _performMemoryWarning]
OrangeDog

3
Para quem está procurando fazer isso com o Swift: digite em expr UIApplication.sharedApplication().performSelector("_performMemoryWarning")vez de usar o normal#selector
funct7 de

27

O Simulate Memory Warningitem de menu do simulador iOS permite simular um aviso de memória.


A única maneira de verificar no dispositivo é realmente forçá-lo, ou seja, usando o aplicativo por longos períodos de tempo ou imagens intensas ou o que quer que seja, irá variar de aplicativo para aplicativo. Uma sugestão pode ser usar um dispositivo mais antigo (3g talvez?) Em vez de um iPhone 4 para ajudá-lo a obter o aviso mais rapidamente.
Jesse Naugher

Obrigado, Jesse, acho que vou apenas adicionar alguns hacks ao meu aplicativo para simular convites para que eu possa executá-lo no simulador e induzir os avisos de memória dessa forma.
BeachRunnerFred

10
A pergunta era sobre a simulação no dispositivo.
KPM

20

Usando instrumentos, use o item de menu: Instrumento -> Simular Aviso de Memória.

Para usar instrumentos em seu aplicativo do Xcode, use o item de menu Produto -> Perfil.


Isso é ainda melhor.
Zappel de

@OrangeDog O que está acontecendo?
ThomasW

2
Bem, nada. Quando eu uso as visualizações de resposta do Enzo, tenho que recarregar quando eu volto a elas, não usando esse método.
OrangeDog

12

Eu re-escrito a resposta de Enzo Tran em Swift:

UIControl().sendAction(Selector(("_performMemoryWarning")), to: UIApplication.shared, for: nil)

Obrigado! O Xcode avisa sobre "nenhum método declarado com o seletor Objective-C", mas isso funciona mesmo assim.
man1

10

Se alguém, por qualquer motivo, tentar fazer isso no Swift 4 - aqui está como alocar 1,2 GB de RAM.

let d = Data.init(repeating: 100, count: 1200000000)
  • Isso é útil para acionar um alerta de aviso em outros aplicativos

Será que fazer algo assim ofuscará as informações reais da memória que estou tentando visualizar em Instrumentos? Embora eu veja que não há uma maneira adequada de fazer isso em um dispositivo físico, se meu objetivo é ver o que está ocupando minha memória no meu aplicativo, parece que isso vai distorcer todos os dados e não já tem uma resposta relativa. Ainda verei o que está ocupando mais , mas não as verdadeiras proporções.
Jake T.

isso trava imediatamente
Daniel Springer

7

Há um comando de menu que o chamará.

Hardware > Simulate Memory Warning do simulador.


8
A pergunta era sobre a simulação no dispositivo.
KPM

2
No Xcode 10 está agora sob o aviso Debug> Simulate Memory.
Sebbo

7

@ChikabuZ convertido para swift 3:

UIControl().sendAction(Selector(("_performMemoryWarning")), to: UIApplication.shared, for: nil)

4

Se alguém, por qualquer motivo, tentar fazer isso no Swift 3 - aqui está como alocar 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;
   }

3
let d = Data.init (repetindo: 100, contagem: 1200000000)
Adobels

2
@Adobels você deve postar isso como uma resposta :)
Koen.

1

Swift 4:

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

Pode executar o acima em resposta a um evento / notificação.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.