jogo android - como armazenar elementos do jogo para que o gc não atire

8

Estou desenvolvendo um jogo para Android e tenho uma pergunta sobre como armazenar os elementos do jogo sem disparar o coletor de lixo.

Meu jogo precisa de uma coleção na qual os elementos do jogo sejam armazenados de acordo com as posições x, y (todos os elementos do jogo têm x, y, largura e altura). A coleção é chamada de cada quadro para recuperar os elementos de acordo com cameraX, cameraY, largura e altura da câmera (o usuário pode rolar o jogo).

Exemplo:

 function draw() {
   tmp = collection.getElements(tmp,cameraX,cameraY,cameraWidth,cameraHeight);
     for(int i = 0; i < tmp.size(); i++) {
        tmp.get(i).draw();
     } 
  }

Atualmente, estou usando a classe Vector para representar os elementos da coleção, mas o gc continua disparando a cada dois minutos. Eu faço todas as minhas alocações antecipadamente. Também modifiquei a função getElements para aceitar mais 1 parâmetro - um vetor temp (alocado antecipadamente) que é preenchido com elementos e depois retornado.

Como devo armazenar os elementos do jogo para que o gc não acione (prefiro nunca, se possível)?

Também adiciono elementos à coleção durante o tempo de execução, também tenho que alocá-los antecipadamente?

Jernej
fonte

Respostas:

3

Sim, se você alocar algo em tempo de execução, ele eventualmente acionará o GC. Geralmente, você contorna isso implementando um pool de objetos ... dessa forma, pode pré-alocar (ou pelo menos coletar novas instâncias para reutilização) todos os objetos, como marcadores e outras entidades, para evitar o acionamento do GC.

editar: você também pode usar um criador de perfil de memória (como o analisador de memória do eclipse ) que pode ajudá-lo a descobrir qual rotina está gerando objetos em tempo de execução.

Joel Martinez
fonte
então instado de usar uma classe Vector use MyObject []? Mas então eu tenho que pré-alocar o tamanho do pool de objetos para poder adicionar e remover objetos dinamicamente ... algo como MyObject [] pool = new MyObject [MAX_OBJECTS]; é isso que você quis dizer?
Jernej
mais especificamente, se você quiser 100% de evitar novas alocações de objeto, precisará alocar cada instância contida nessa matriz. Eu escrevi uma classe em C # para o framework XNA que atinge um bom equilíbrio ... ele só cria novas instâncias quando o pool não possui uma instância existente para fornecer. O resultado é que os primeiros segundos podem alocar alguns objetos, mas quando atingimos o número máximo de instâncias simultâneas, nenhuma nova alocação ocorre. Deve ser relativamente fácil para converter em java: codecube.net/2010/01/xna-resource-pool
Joel Martinez
2

Também sugiro a leitura do código-fonte da Replica Island , desenvolvido por um engenheiro do Android. Ele tem uma classe de pool de objetos genéricos que pode ser estendida para pools de objetos personalizados. Ele também tem uma classe de matriz personalizada (com recursos de adição / exclusão / pesquisa) para evitar a necessidade de usar um iterador ao percorrer uma matriz de objetos.

Também gostaria de mencionar que o DDMS no Android SDK no Eclipse pode rastrear alocações de memória (consulte a guia Rastreador de alocação na imagem).

f20k
fonte