Android: OutofMemoryError: o tamanho do bitmap excede o orçamento da VM sem motivo para ver

Estou tendo uma exceção OutOfMemory com uma galeria com JPEGs de 600x800 pixels.

O ambiente

Eu tenho usado a Galeria com imagens JPG em torno de 600x800 pixels.

Como meu conteúdo pode ser um pouco mais complexo do que apenas imagens, eu configurei cada exibição como um RelativeLayout que agrupa o ImageView com o JPG.

Para "acelerar" a experiência do usuário, eu tenho um cache simples de 4 slots que pré-busca (em um looper) cerca de 1 imagem à esquerda e 1 imagem à direita na imagem exibida e os mantém em um HashMap de 4 slots.

A plataforma

Estou usando o AVD de 256 RAM e 128 Heap Size, com uma tela de 600x800. Isso também acontece em um destino do Entourage Edge, exceto que, com o dispositivo, é mais difícil depurar.

O problema

Eu tenho recebido uma exceção:

OutofMemoryError: bitmap size exceeds VM budget

E isso acontece ao buscar a quinta imagem. Eu tentei alterar o tamanho do meu cache de imagem e ainda é o mesmo.

O estranho: não deve haver um problema de memória

Para garantir que o limite de heap esteja muito longe do que eu preciso, defini uma matriz fictícia de 8 MB no começo e a deixei sem referência para que seja despachada imediatamente. É um membro do segmento de atividade e é definido como a seguir

static { @SuppressWarnings("unused")
byte dummy[] = new byte[ 8*1024*1024 ]; }    

O resultado é que o tamanho da pilha é de quase 11 MB e é totalmente gratuito.Nota Eu adicionei esse truque depois que ele começou a falhar. Isso torna o OutOfMemory menos frequente.

Agora estou usando DDMS. Pouco antes da falha (não muda muito após a falha), o DDMS mostra:

ID  Heap Size   Allocated   Free       %Used    #Objects
1   11.195 MB   2.428 MB    8.767 MB   21.69%   47,156  

E na tabela de detalhes mostra:

Type  Count  Total Size   Smallest   Largest   Median    Average
free  1,536  8.739MB      16B        7.750MB   24B       5.825KB

O maior bloco é 7,7MB. E, no entanto, o LogCat diz:

ERROR/dalvikvm-heap(1923): 925200-byte external allocation too large for this process.

Se você se preocupa com a relação entre a mediana e a média, é plausível supor que a maioria dos blocos disponíveis seja muito pequena. Contudo,existe um bloco grande o suficiente para o bitmap, é 7,7 milhões. Como é que ainda não é suficiente?

Nota: gravei um rastreamento de heap. Ao analisar a quantidade de dados alocados, não parece que mais de 2 milhões foram alocados. Corresponde ao relatório de memória livre do DDMS.

Será que tenho algum problema como fragmentação de heap?Como resolvo / solução alternativa do problema?O heap é compartilhado com todos os threads?Será que eu interpreto a leitura do DDMS de maneira errada e não há realmente nenhum bloco de 900K para alocar? Se sim, alguém pode me dizer onde posso ver isso?

Muito obrigado

Meymann

questionAnswers(5)

yourAnswerToTheQuestion