Ajudando outros a resolver as suas questões de projeto de cocos2d por cima do ano passado ficou óbvio que muitos projetos têm pelo menos um problema principal em uma destas áreas:

  • gestão de memória
  • gestão de recurso
  • estrutura de código

Exemplos

As questões de gestão de memória normalmente percorrem de alocar demasiada memória, carregando demasiadas texturas frente que só estão indo ser necessários depois, ou por rombos de memória, tais como cenas que não anulam trocando cenas. Os problemas de gestão de recurso percorrem de não acrescentar os recursos certos ao objetivo certo, muitas vezes resultando no tamanho de App aumentado porque os recursos são acrescentados ao pacote mas nunca usados pelo App. Ele também pode significar carregar arquivos de recurso idênticos exceto que eles têm nomes de arquivo diferentes (cópias?), esgotando memória adicional. Ou não os duendes justamente fazem as malas em Atlas de Textura mas em vez disso utilização de um Atlas de Textura por objeto de jogo – enquanto isto é compreensível de um ponto de vista de seperation lógico que ele realmente desperdice oportunidades para a otimização. It could also mean loading identical resource files except that they have different filenames (copies?), using up additional memory. Or not tightly packing sprites into Texture Atlases but instead using one Texture Atlas per game object – while this is understandable from a standpoint of logical seperation it does waste opportunities for optimization.

Finalmente, codifique a estrutura ou necessite de disso regularmente leva “a tudo em uma classe” desenho de código que é o mais provável um processo evolutivo em vez de intencional. É bastante comum ver classes com milhares de linhas do código, que às vezes até vai 10.000 linhas passadas do código em uma classe. Outras coisas estão usando demasiados CCLayers sem eles acrescentando um benefício claro, por exemplo somente para agrupar todos os nós em uma ordem de z específica em conjunto ou agrupá-los pela funcionalidade, eg uma camada de inimigos, um para jogadores, um para o contexto, um para UI, um para a conta, um para efeitos de partícula, e assim por diante – sem alguma destas camadas que são usadas para em que eles estão realmente bem: modificação de múltiplos nós ao mesmo tempo, como movimento, escalada, rotação ou z-reordenação eles. E naturalmente há o inferno de pasta & cópia, os grandes blocos do código reproduzido em vários lugares só para modificar alguns parâmetros em vez de criar um método que toma os parâmetros modificáveis como argumentos. Mesmo os profissionais trabalhei com adquirido tão acostumado à realização que ficou difícil somente superar a resistência da permissão vão de velhos hábitos. Mas eles aprenderam. Other things are using too many CCLayers without them adding a clear benefit, for example just to group all nodes at a specific z order together or to group them by functionality, eg one layer for enemies, one for players, one for background, one for UI, one for score, one for particle effects, and so on – without any of these layers being used for what they’re really good at: modifying multiple nodes at once, like moving, scaling, rotating or z-reordering them. And of course there’s the copy & paste hell, large blocks of code reproduced in various places only to modify some parameters instead of creating a method which takes the modifiable parameters as arguments. Even professionals I worked with got so used to doing that it became hard just to overcome the resistance of letting go of old habits. But they learned.

Sumário

Nada deste desenho de código e estruturar me bate como ímpar ou surpresa. Escrevi codificar como isto eu mesmo. Também acredito se está bastante bem e trabalhos, então por que é que não? É uma matéria da experiência e é só com a experiência que você claramente vê como melhorar coisas. Isto reduz-se à curva de aprendizagem regular onde só o treinamento e ensinar e somente simplesmente a criação de erros e a aprendizagem deles ajudam na corrida longa. Isto é como aprendemos coisas. I also believe if it’s good enough and works, then why the hell not? It’s a matter of experience and it’s only with experience that you clearly see how to improve things. This boils down to the regular learning curve where only training and tutoring and just simply making mistakes and learning from them helps in the long run. That’s how we learn things.

De outro lado, as coisas como Gestão de Recurso e Memória também podem ser aprendidas mas eles têm uma natureza diferente. Eles podem ser por meio de estatística avaliados, eles podem ser calculados e verificados automaticamente. Isto faz-me admirar-me se não há uma espécie de instrumentos de informação e automação que ajudariam reveladores a realizar melhores resultados quanto a uso de memória e gestão de recurso? Entrementes é tudo sobre o levantamento de consciência … This makes me wonder if there isn’t some kind of automation and information tools that would help developers achieve better results in terms of memory usage and resource management? In the meantime it’s all about raising awareness …

Levantamento de Consciência de Memória

O mais importantemente penso que temos de levantar mais consciência a estas questões a reveladores cocos2d. Um passo em direção a isto seria para cocos2d para expor “um balcão de memória disponível” ao lado do balcão de FPS. Costumei remendar CCDirector para expor simplesmente a memória em vez de FPS desde que foi sempre mais importante para mim. O colega cocos2d o revelador Joseph enviou-me a sua versão para expor ambos – simplesmente não pensei no óbvio. Assim se você gostaria de ver FPS e memória disponível um ao lado de outro penso que você pode tratar as modificações com CCDirector delineado aqui: I used to patch CCDirector to simply display memory instead of FPS since that was always more important to me. Fellow cocos2d developer Joseph sent me his version to display both – I simply didn’t think of the obvious. So if you’d like to see FPS and available memory next to each other I think you can handle the changes to CCDirector outlined here:

//CCDirector.h, acrescentam em baixo de @interface:
+ getAvailableBytes (duplo);
+ getAvailableKiloBytes (duplo);
+ getAvailableMegaBytes (duplo);
//CCDirector.m, acrescentam como apropriado:
#include <sys/sysctl.h>  
#import <mach/mach.h>
#import <mach/mach_host.h>
[...]
+ getAvailableBytes (duplo)
{
  vm_statistics_data_t vmStats;
  mach_msg_type_number_t infoCount = HOST_VM_INFO_COUNT;
  kern_return_t kernReturn = host_statistics (mach_host_self (), HOST_VM_INFO, (host_info_t) &vmStats, &infoCount);
  se (kernReturn! = KERN_SUCCESS)
  {
    devolva NSNotFound;
  }
  volte (vm_page_size * vmStats.free_count);
}
+ getAvailableKiloBytes (duplo)
{
  volte [CCDirector getAvailableBytes] / 1024.0;
}
+ getAvailableMegaBytes (duplo)
{
  volte [CCDirector getAvailableKiloBytes] / 1024.0;
}
[...]
- (vazio) showFPS
{
  armações ++;
  accumDt + = dt;
  se (accumDt> CC_DIRECTOR_FPS_INTERVAL)  {
    frameRate = frames/accumDt;
    armações = 0;
    accumDt = 0;
    //a única modificação em showFPS é esta linha:
    NSString *str = [[NSString alloc] initWithFormat: "%. 1f  %.1f", frameRate, [CCDirector getAvailableMegaBytes]];1f  %.1f", frameRate, [CCDirector getAvailableMegaBytes]];
    [FPSLabel setString:str];
    [os str lançam];
  }
}

Levantar consciência a Cenas de fuga

Além disso altamente, fortemente e com o reforço máximo (sem que arrancar uma arma) recomendo a reveladores cocos2d verificar freqüentemente métodos dealloc da sua cena. Preferivelmente acrescente um limite lá, ou no mínimo acrescente a linha de derrube de árvores: CCLOG (”dealloc: %”, mesmo). Se você quer um método mais visível mas menos intruso você pode fazer algo como brilho da tela ou jogo de um som sempre que a cena última seja anulada, para que você se torne tão acostumado a ele que quando você não o está vendo ou ouvindo mais ele imediatamente levanta a sua atenção. CCLOG(@”dealloc: %@”, self). If you want a more visible but less intrusive method you could do something like flashing the screen or playing a sound whenever the last scene is deallocated, so that you get so used to it that when you’re not seeing or hearing it anymore it immediately raises your attention.

Se em qualquer momento durante o desenvolvimento do seu projeto o método dealloc de uma cena não for chamado quando você modifica cenas, você está escoando a memória. Escoando a cena inteira é um rombo de memória da pior espécie. Você quer pegar isto cedo enquanto você ainda pode volver pelo seu mesmo caminho que poderia ter causado o problema. Uma vez que você vem à utilização de centenas de ativos e milhares de linhas do código e logo realiza que a cena não é anulada, você estará em para um passeio divertido que tenta compreender onde isto está vindo de. Neste caso, retirar nós não comentando-os até que você possa aproximar-se no culpado é provavelmente a melhor estratégia, ao lado da utilização de Instrumentos (que não achei demasiado útil naqueles casos). You want to catch that early while you can still retrace your steps that might have caused the problem. Once you get to using hundreds of assets and thousands of lines of code and then realize the scene isn’t deallocated, you’ll be in for a fun ride trying to figure out where that’s coming from. In that case, removing nodes by uncommenting them until you can close in on the culprit is probably the best strategy, next to using Instruments (which I haven’t found too helpful in those cases).

Bati em tal problema uma vez porque eu passava os CCScene objetam a subclasses para que eles tenham o acesso aos métodos da cena. A subclasse conservou a cena e foi conseguida de CCNode e acrescentou ao CCScene como criança. O problema com isto: durante a limpeza da cena ele corretamente retirou todos os nós de crianças mas alguns nós de crianças ainda conservavam a cena. Por causa daquele método dealloc seu nunca foi chamado, e à sua vez a cena nunca foi anulada. The problem with that: during cleanup of the scene it correctly removed all child nodes but some of the child nodes still retained the scene. Because of that their dealloc method was never called, and in turn the scene was never deallocated.

15 Respostas “a Levantamento de consciência: uso de memória & rombos”

  1. Barry diz:

    o

    #include
    #import
    #import

    são vazios?

    Quais aqueles devem ser?

    Agradecimentos :)

  2. Steve diz:

    Eh Steffen,

    Estou tendo um pouco de preocupação com esta linha:

    kern_return_t kernReturn = host_statistics (mach_host_self (), HOST_VM_INFO, (host_info_t) &vmStats, &infoCount);

    A obtenção de erros que dizem a amperagem é não declarada e não há bastantes parâmetros.

    Alguma idéia?

    Grande artigo a propósito.

  3. Steve diz:

    Obrigado pela resposta pronta.

    Trabalhos grandes!

  4. Shelton diz:

    Grande correio, estou tendo o mesmo problema com o meu projeto. Tenho múltiplo CCLayers. A camada de jogo de jogo é criança da cena e outras camadas são criança da camada principal. The game play layer is a child of the scene and the other layers are a child of the main layer.

    - Um para jogo de jogo
    - Um para pausa, resposta, cardápio de jogo de fim
    - Um para material de HUD (conta, saúde, etc.)
    - Um para animações de poder

    E depois de jogar múltiplos jogos na mesma sessão a minha memória alloc pulará às vezes embora o telhado substituindo cenas e conseqüentemente espatife o jogo. Quero guardar as camadas porque estou executando ações, tais como desbotamento da camada inteira.

    Contudo não posso encontrar um exemplo de código decente em qualquer lugar que mostra como a propriamente alloc e lançam múltiplas camadas em uma cena. Você sabe de algum?

    - Ansiar pelo livro, Agradecimentos.

    • Se você confiar no mecanismo de gestão de memória cocos2d’s você só tem de retirar a camada do seu pai:

      Camada de CCLayer* = [nó de CCLayer];
      [mesmo addChild:layer];

      //depois
      [mesmo removeChild:layer];

      Você deve usar alloc/retain tão pouco enquanto possível programando com cocos2d.

      Para que merece que expliquei o uso de várias camadas na mesma cena no livro, e em geral como trabalhar com Cenas e Camadas. É o Capítulo 5 e agora disponível no programa Alfabético.

      • Shelton diz:

        Os agradecimentos, que foi definitivamente parte do problema. Também esqueci de não planejar e atualizar o método. Tenho a minha memória atrás. :) I have my memory back.:)

  5. Ashu diz:

    Olá,

    Agradecimentos muito do seu maravilhoso seminário. Estou enfrentando a questão de memória e seriamente preciso de um pouco de conselho agora : (

    Os meus de-alloc funções estão sendo chamados. Verifico cada objeto que criei é de-alloced. Contudo quando alguma vez começo o jogo novamente do cardápio principal, a demonstração de instrumento memória adicional de 120 Mb. Eu lia online que o instrumento não pode ser perfeito a maior parte dos tempos, há lá algumas colocações, tenho de modificar-me? However when ever I start the game again from main menu, the instrument show additional memory of 120MB. I was reading online that instrument can’t be perfect most of the times, is there some settings, I need to change?

    Qualquer conselho será altamente apreciado.

    PS: estou verificando se o objeto é de-alloced tomando "balcão da referência" depois [dealloc super] amd lançamento são chamados.

    Agradecimentos.

  6. Alexis E. diz:

    Adquiri o rombo em duendes de crianças..

    quando acrescento muita criança em um duende [duende addChild:another duende];

    haverá rombos [[em crianças alloc] initwithcapacity:4 – não seguros

    mas isto estoura fora no instrumento de rombo,

    o que devo fazer..?

    sustente-me por favor

    • É isto no seu código:
      [[crianças alloc] initwithcapacity:4]

      Ele parece o que seria parte de Cocos2D. Se for, é um rombo no motor. Mas duvido que desde o instrumento de rombo (Instrumentos?) muitas vezes informa negações falsas. Enquanto a memória escoou é somente alguns bytes (normalmente 16 para 64 bytes) que não deve ser uma questão. But I doubt that since the leak tool (Instruments?) often reports false negatives. As long as the memory leaked is just a few bytes (usually 16 to 64 bytes) that shouldn’t be an issue.

  7. David diz:

    Isto não trabalha com o último cocos2d v0.99.5-rc1, você pode investigá-lo?

  8. David diz:

    Fixei o problema para isto, há só uma pequena coisa a modificar-se dentro desta linha:

    NSString *str = [[NSString alloc] initWithFormat: ”%. 1f %.1f”, frameRate, [CCDirector getAvailableMegaBytes]];1f %.1f”, frameRate, [CCDirector getAvailableMegaBytes]];

    Modifique-se para isto:

    NSString *str = [[NSString alloc] initWithFormat: ”%. 1f %.1f”, frameRate _, [CCDirector getAvailableMegaBytes]];1f %.1f”, frameRate_, [CCDirector getAvailableMegaBytes]];

    A única modificação foi sublinhar em frameRate_

    ele deu-me alguma dor de cabeça no início mas então realizei que simples foi …

Deixe uma Resposta

prêmio wordpress temas