domingo, 20 de abril de 2014

Alocação de Memória: Struct vs Memory Allocation


Esse post surgiu de uma dúvida que está no Fórum do Netduino: Veja

No fórum, um membro Nofaca fez uma pergunta sobre alocação de memória dizendo que sempre ocorre um problema de OutOfMemoryException quando ele tenta alocar memória para arrays de estruturas.

Fato é que .NETMF tem uma forma própria de alocar memória, as vezes queremos que .NETMF seja igual ao .NET convencional mas não é bem assim, existem algumas limitações relacionadas com a natureza do processador, em outras palavras o .NETMF faz uma parte de um "tipo RTOS" - MSDOS transformando para alto nível o que está em muito baixo nível.

Continuando, ele colocou o seguinte exemplo de código:

 [Serializable, StructLayout(LayoutKind.Sequential)]  
 struct SColor  
 {  
      public byte R;  
      public byte G;  
      public byte B;  
      public byte Alpha;  
 }  

Fato é que ele pretende criar uma estrutura simples que armazena informações de cor. SColor seria uma estrutura para armazenamento de informações de cor RGB e intensidade (Alpha). Segundo o que ele disse não está conseguindo alocar a memória para essa estrutura. Eu tentei confirmar mas funciona bem com a classe de inteiro e com a estrutura SColor!

 Debug.Print("Memory free: " + Debug.GC(true).ToString());  
 int[] _buffer = new int[128 * 64];  

 Debug.Print("Memory free: " + Debug.GC(true).ToString());  
 SColor[] _colors = new SColor[128 * 64];  

A saída do debug dele foi:

 Memory free: 96948  
 Failed allocation for 8194 blocks, 98328 bytes  
 Failed allocation for 8194 blocks, 98328 bytes  

Fato é que existe pouca memória no Netduino isso faz com que facilmente o programa saia do espeço de memória utilizável.

Conforme o Chris Walker respondeu o NETMF teve alguma sobrecarga de memória adicional para cada variável criada. Dessa forma a memória extra utilizada foi mapeada para armazenanda a estrutura e as utilizações da estruturam, ou seja, deu overflow de memória... Quando em um código solto isso não afeta em nada, entenda-se um código solto como um código específico e pequeno.

A alternativa que o Chris Walker deu para esses casos é otimizar é compilando a estruturas dentro do próprio .NETMF compilando-o novamente! Solução Supersaiadin !!!

Como uma solução alternativa também seria trabalhar com array's simples de 4bytes identificados como ocorre no C. Isso reduz a necessidade de uma estrutura exclusiva para a aplicação em questão e reduz com isso a memória de código/uso utiliza para a estrutura. Para não ficar dependente do desmonte seria possível criar estruturas estilo #defines.

Achei interessante a dúvida porque as vezes temos muitos problemas com locação de memória, quem não trabalhou com a conversão de ponto fixo para ponto flutuante não tem ideia de como era difícil... saber a ordem de grandeza de tudo, estudar o erro e a imprecisão em função de onde se colocava a vígula, Q10, Q15, Q18, etc... As vezes isso que define a otimização de uma aplicação, não trata-se de um simples preciosismo mas sim de um recurso para utilização da ferramenta - Netduino - em sua plenitude.

Nenhum comentário:

Postar um comentário