Android Entendendo os tamanhos de heap

Sou relativamente novo no desenvolvimento do Android e não consigo entender a exceção Java sem memória. Eu sei que isso significa que meu aplicativo ultrapassou o orçamento da VM, mas depois de pesquisá-lo muitas vezes, ainda não consigo entender esse conceito. Eu tenho medo que meu aplicativo usa muita memória porque eu tenho seis seletores de botão por tela com dois bitmaps para cada seletor que são cerca de 20 kb cada, de acordo com a guia de propriedades. No meu G2x com raiz, defini o orçamento da VM como 12 MB, reiniciei meu telefone e executei meu aplicativo sem problemas. Eu estou desenhando drawables em cada onDestroy () e insinuando no GC para rodar aqui também. Depois de usar o aplicativo por um tempo no emulador clico em "Cause GC" na tela do DDMS e os resultados são ID = 1, Tamanho do heap 6.133 MB, Alocados 2.895MB, Free 3.238 MB,% Used 47.20, # Objects 52,623.

É aqui que eu não entendo o que está acontecendo, meu emulador está configurado para 24 MB de VM. Onde é esse numero? O problema real que estou tendo é que se eu definir o emulador para 16MB de VM meu aplicativo falha na segunda atividade com a exceção de memória insuficiente. Como é que não falha no meu telefone com a VM configurada para 12 MB ou no meu antigo telemóvel HTC Magic com 12 MB de stock de VM? Vocês também acham que meu aplicativo está ocupando muita memória? Não tenho idéia se esses números de DDMS são bons ou não. Obrigado pelo seu tempo.

Quanto ao meu código, eu tenho todas as imagens especificadas em layouts XML. Eu não faço nada de forma programática com eles, exceto para adicionar ouvintes a eles. Eu encontrei este código aqui e adicionei a cada atividade que eu tenho ...

@Override
protected void onDestroy() {
    super.onDestroy();

    unbindDrawables(findViewById(R.id.myRootLayout));
    System.gc();
}

private void unbindDrawables(View view) {
    if (view.getBackground() != null) {
        view.getBackground().setCallback(null);
    }
    if (view instanceof ViewGroup && !(view instanceof AdapterView)) {
        for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {
            unbindDrawables(((ViewGroup) view).getChildAt(i));
        }
        ((ViewGroup) view).removeAllViews();
    }
}

Caso contrário, tudo o que faço é adicionar onClickListeners aos botões que têm o fundo PNG. Gostaria de aprender como especificar programaticamente os planos de fundo dos botões, mas preciso que o seletor funcione como no foco, na impressora, sem foco, mas pressionado, etc., para que os planos de fundo dos botões mudem de acordo com a interação do usuário. Eu revi os documentos sobre isso, mas parece esmagadora, é por isso que eu pensei em começar aqui com o básico de gerenciar Heaps e trabalhar até especificar seletores no código. Isso pode não fazer sentido, mas há uma quantidade "saudável" de alocação de memória que um aplicativo pode alocar sem chegar perto da exceção de falta de memória? Por exemplo, se um aplicativo alocou 6MB, ele deve ficar bom, mas 8MB o empurrariam, há limites como esse na alocação de memória? Obrigado novamente Alex Lockwood pela sua resposta Eu vou ler e reler novamente até que este material faça sentido para mim

questionAnswers(2)

yourAnswerToTheQuestion