Gerenciamento de memória e tamanho dos arquivos em grandes aplicativos utilizando o Modules do Flex 2.0.1
Sistemas realmente grandes feitos em Flex tendem a ficar com um tamanho em Kbytes igualmente grande. Além disso, com um sistema tão grande, é bem provável que os usuários utilizem apenas parte dele. Assim, o usuário ter de carregar o sistema inteiro para poder utilizá-lo não é uma idéia coerente.
Já no Flex 1.5 em aplicativos muito grande nós utilizávamos o componente Loader para carregar aplicativos (no caso de um portal) ou módulos de aplicativos, de acordo com a necessidade do usuário.
Mas nem sempre a banda e a quantidade de dados transferida é um problema (em casos em que o aplicativo só funcionará em redes locais, por exemplo): as vezes o vilão da vez pode ser o consumo de memória.
Quem já utilizou o SWFLoader para carregar um outro aplicativo em Flex pode ter notado que na verdade o aplicativo nunca é totalmente descarregado da memória (veja: um aplicativo Flex, e não um simples filme SWF), e o pior: tantas forem as vezes que este aplicativo for “carregado” via SWFLoader, tantas vezes ele irá para a memória! (aliás, vale notar que o objetivo aqui não é criticar o Flash Player no tocante ao uso de memória. Seu garbage collector faz um ótimo trabalho, mas os objetos têm de estar disponíveis para tal).
Nessa situação, o uso do ViewStack traz um ótimo benefício: nenhuma das telas será carregada duas vezes na memória, já que simplesmente uma tela é escondida e outra é revelada. O consumo de memória não irá crescer, não haverá telas duplicadas instânciadas, mas o tamanho do arquivo total será muito grande.
Mas o que fazer quando as duas questões, memória e tamanho dos arquivos, se tornam um problema e devem ser consideradas?
Muitas pessoas (eu incluso) acharam que a funcionalidade de Module no Flex 2.0.1 era a resposta simples e fácil que procurávamos, no estilo “instalar-e-usar”, mas não é bem assim. Além da funcionalidade ser similar (o ModuleLoader funciona do mesmo modo que o SWFLoader) e ambos serem baseados no mesmo componente do Flash (o flash.display.Loader), o problema sobre o não real descarregamento da memória está muito mais ligado à natureza do Flash e do Flex SDK (que é muito inter-dependente entre si).
Pensando nisso que trabalhei em uma simples abordagem hibrída com Modules (para separar os módulos em diferentes arquivos que serão carregados apenas uma vez) e com o ViewStack (para incremento nulo de memória ao mostrar uma tela que já foi mostrada anteriormente).
A idéia é simples: um ViewStack de ModuleLoaders e um pequeno código para verificar se o Modulo já foi anteriormente carregado. Assim, caso isso seja verdadeiro, o ViewStack apenas mostra o módulo; caso contrário é feito o download do módulo e este atribuído como um dos filhos do ViewStack. Tantas vezes quanto um módulo for exibido, não haverá incremento na memória.

O gráfico acima mostra o desempenho de quatro abordagens (embora o StackedModules tenha sido criado depois desse estudo) em relação ao consumo de memória para uma aplicação de demonstração. Tanto o SWFLoader quando o ModuleLoader puro e simples têm um desempenho similar. As interações 4, 5 e 6 são de carregamento de um módulo (ou aplicativo no caso do SWFLoader) já carregado anteriormente. Note que o consumo de memória continua crescendo nessas interações, diferente do uso do ViewStack e do StackedModules. Esse gráfico faz parte de um estudo sobre essas abordagens em uma aplicação de exemplo. Os valores são médias aritméticas de pelo menos duas medições.

Resolvido o problema de memória com a abordagem do StackedModules (inserindo os módulos carregados como filhos do ViewStack e apenas alternando a tela vísivel no mesmo), a outra questão a verificar é o tamanho dos arquivos transferidos. O gráfico cima ilustra bem a diferença: enquanto o ViewStack tem um custo inicial muito grande (afinal, é feito o download de tudo), o StackedModules (e isso é inerente ao funcionamento do Modules, tal como no SWFLoader) faz o download à medida que é necessário, e isso se torna ainda mais benéfico ao considerarmos que nem sempre um usuário irá acessar todos os módulos, o que tornaria o tráfego com o o Modules menor que o ViewStack. Para esse teste, os módulos foram compilados com dynamic linking, reduzindo o tamanho do SWF.
O projeto de prova de conceito está disponível para download: StackedModules.zip. O componente ModuleLoaderWithProgress incluído apresenta uma barra de carregamento (download) do módulo, mas pode ser substituído com a sua própria implementação do ModuleLoader. Importante: utilize o build.xml incluso para compilar (permitindo o dynamic linking), e não o Flex Builder diretamente. O consumo de memória foi aferido pelo flash.system.System.totalMemory.
O conceito de Stacked Modules é uma boa solução para o gerenciamento de memória e tráfego em grandes aplicativos, mas não deve ser considerada única solução caso esses quesitos sejam vitais em seu projeto.
27 comentários para “Gerenciamento de memória e tamanho dos arquivos em grandes aplicativos utilizando o Modules do Flex 2.0.1”
Ótimo artigo! A genialidade de sua solução está na simplicidade e na criatividade.
Parabens pelo artigo Fabio, estou com um projeto pra uma intranet e esse artigo com certeza será muito util.
ate mais
Leonardo França
[...] Veja o artigo completo: http://blog.dclick.com.br/2007/01/23/gerenciamento-de-memoria-e-tamanho-dos-arquivos-em-grandes-aplicativos-utilizando-o-modules-do-flex-201/ (No Ratings Yet) Loading … del.icio.us | digg! | furl | reddit | rojo | yahoo! | rec6 | dzone | Bloglines | Eu Curti [...]
Muito interessante essa abordagem Fabio, estava procurando algo assim e o seu post/exemplo caiu como uma luva. Parabéns !
Só não entendi uma coisa, o que vc quis dizer com compilar usando ‘dynamic linking’ ?
Nos testes que eu fiz aqui, compilei normalmente usando o ‘mxmlc.exe’ e funcionou também, vc vê algum problema ? Tem como configurar o flex builder para compilar e gerar esses arquivos separados ao invés de usar o prompt ?
Reparei que os arquivox mxml, deve ser do tipo ‘Module’, se fosse do tipo ‘Application’ funcionaria ? qual a diferença ?
valeu Fábio.
[]’s
mindu
Mindu,
Dynamic linking é um recurso para compilar o arquivo SWF com o mínimo de dependências possíveis, considerando que as demais dependências estarão presentes no arquivo que o carregou.
Assim, o seu Aplicativo.mxml já inclui uma série de componentes (por exemplo Panel, Label, TextInput, etc) que também serão utilizados por seu Modulo.mxml. Assim o Modulo.mxml, ao ser compilado, “externaliza” a dependência dessas classes para seu outro swf. O objetivo maior é otimizar e reduzir o tamanho dos arquivos.
Eles poderiam ser Applications se fossem utilizado em conjunto com o SWFLoader. O ModuleLoader é utilizado para carregar Modules, como no arquivo que disponibilizei. Teoricamente o efeito é o mesmo, mas o Modules é mais flexível para esse propósito específico de módulos de aplicativos.
[]s!
manual da memoria frex halloem
Bacana o artigo,
Será muito útil para aplicações posteriores e revisar algumas já feitas!
Meus Parabéns
Fabio muito interessante sua matéria sobre o consumo de memoria Parabéns .
Estou com uma duvida , seguinte fiz um modulo que implementa componentes que eu criei , na tag do modulo fica assim :
quando executo o mxmlc o compilador diz : Type was not found or was not a compile-time constant : COMBOC, eu vi no seu exemplo no aquivo build.mlx que tem parametros para o compilador , vc poderia me ajudar nesse problema ? desde já agredeço sua Atenção
Cool.
Cool.
Cool…
Cool.
Sorry 
Cool!
Interesting…
Fábio, artigo muito interessante, com propriedade, foi muito útil para mim, parabéns e muito obrigado era exatamente o que eu estava procurando saber.
Esse artigo realmente me ajudou muito. Muito obrigado mesmo. Continuem evoluindo.
Após apreciar seu bom conhecimento, gostaria de aproveitar este espaço, para pedir um auxílio. Tenho um arquivo .fla, que ficou muito pesado, com 7,21 mb (megabites), e não conseguí mais abrí-lo de maneira alguma. Já aumentei a memória virtual, dentre várias outras tentativas. Há alguma meneita de conseguir abrir novamente o referido arquivo?
Abraços.
REPETIÇÃO DA MENSAGEM ANTERIOR, COM ENDEREÇO DE E-MAIL PARA CONTATO
Após apreciar seu bom conhecimento, gostaria de aproveitar este espaço, para pedir um auxílio. Tenho um arquivo .fla, que ficou muito pesado, com 7,21 mb (megabites), e não conseguí mais abrí-lo de maneira alguma. Já aumentei a memória virtual, dentre várias outras tentativas. Há alguma meneita de conseguir abrir novamente o referido arquivo?
Se souber, por favor, entre em contato: vanrafa2@yahoo.com.br
Abraços.
Excelente Fábio! Quem dera todos os artigos que a gente encontra por ai fossem completos como o seu!
Ótimo exemplo!!!
Porém, creio ter encontrado algo desfavorável no uso de módulos.
Gostaria de pedir a ajuda dos colegas para as 2 seguintes questões.
Primeira questão.
Vamos imaginar que estamos usando esse mesmo exemplo com gráficos,
porém,
a melhor prática seria que as “telas dos gráficos” fossem componentes “caixa-preta”, ou seja, que fizessem apenas a função de exibir valores, sem questionar a origem deles.
Num exemplo sem módulos, poderiamos fazer isso de forma simples,
usando uma “[Bindable] public var myModules:ArrayCollection=null;”
e deixarmos que o componente-pai cuidasse de preenchê-lo.
Porém, eu nunca encontrei uma forma de fazê-lo.
Algum dos colegas poderia me ajudar nesse ponto?
Segunda questão.
Vamos analisar uma estratégia simples de programar(sem módulos),
o Código funciona bem, vamos separar em componentes agora….
(espero não ter ido rápido demais…)
o que quero dizer é,
Como podemos levantar eventos entre o MX:MODULE e MX:MODULELOADER
Ótimo exemplo!!!
Porém, creio ter encontrado algo desfavorável no uso de módulos.
Gostaria de pedir a ajuda dos colegas para as 2 seguintes questões.
Primeira questão.
Vamos imaginar que estamos usando esse mesmo exemplo com gráficos,
porém,
a melhor prática seria que as “telas dos gráficos” fossem componentes “caixa-preta”, ou seja, que fizessem apenas a função de exibir valores, sem questionar a origem deles.
Num exemplo sem módulos, poderiamos fazer isso de forma simples,
usando uma “[Bindable] public var myModules:ArrayCollection=null;”
e deixarmos que o componente-pai cuidasse de preenchê-lo.
Porém, eu nunca encontrei uma forma de fazê-lo.
Algum dos colegas poderia me ajudar nesse ponto?
Segunda questão.
Vamos analisar uma estratégia simples de programar(sem módulos),
(mx:Application)
(mx:Script)
(![CDATA[
[Bindable] private var s:String=”texto”;
]])
(/mx:Script)
(mx:VBox)
(mx:Label id=”label1″ text={s}/)
(/mx:VBox)
(mx:HBox)
(mx:Button id=”bt1″ click=”texto=’modifiquei o texto’”/)
(/mx:HBox)
(/mx:Application)
o Código funciona bem, vamos separar em componentes agora….
(mx:Application)
(mx:Script)
(![CDATA[
[Bindable] private var s:String=”texto”;
]])
(/mx:Script)
(local:MeuVBox texto=”{s}”/)
(local:MeuHBox quandoClicou=”texto=(event as MeuEvento).s”)
(/mx:Application)
(espero não ter ido rápido demais…)
o que quero dizer é,
Como podemos levantar eventos entre o MX:MODULE e MX:MODULELOADER
Estou com esta mesma dúvida:
“Fabio muito interessante sua matéria sobre o consumo de memoria Parabéns .
Estou com uma duvida , seguinte fiz um modulo que implementa componentes que eu criei , na tag do modulo fica assim :
quando executo o mxmlc o compilador diz : Type was not found or was not a compile-time constant : COMBOC, eu vi no seu exemplo no aquivo build.mlx que tem parametros para o compilador , vc poderia me ajudar nesse problema ? desde já agredeço sua Atenção”
Olá Fabio,
Muito interessante o artigo. Tanto que adotei para um sistema que estou fazendo. Mesmo que o Flex 3 agora me possibilite chamar o garbage.
Mas a dúvida é a seguinte:
Antes eu usava o onCreationComplete para executar algo que eu gostaria que a aplicação executasse sempre na primeira vez que o módulo era acessado.
Como vc faz isso agora, ele só exeuta a primeira vez, se eu “fechar” (no meu caso posiciono o stack no item 0) e abrir, ele não vai mais chamar a função.
Existe algum outro evento? show, activate, etc..
Obrigado.
[...] http://blog.dclick.com.br/2007/01/23/gerenciamento-de-memoria-e-tamanho-dos-arquivos-em-grandes-apli... [...]
Estou aprendendo Flex a pouco tempo (1 semana) fiz uma pequena funcao p acompanhar o uso da memoria, nao sei se pode ser util para alguem, mas p mim esta sendo, pois posso acompanhar o comportamento da memoria, comforme vou navegando no projeto, nao sei se é a forma certa, qq coisa falem…
Notei q no Explorer o flex ocupa muito menos memoria, inicia com 5M e no FF o mesmo projeto inicia com 18M, sendo q o explorer esta com a versao 9.0.124 do player do flash e no FF a 9.0.115, entao esta diferenca pode ser (provavenmente) da versao do player e nao do navegador…
Colocar este campo de texto no projeto:
Colocar esta funcao no arquivo .as :
public function atualizaMem():void
{
var k:int = System.totalMemory / 1024;
var m:int = k / 1024;
mostraMemoria.text = String(k)+” Kb / ” + String(m)+” Mb”;
}
Adicionar comentário
Ótimo artigo! A genialidade de sua solução está na simplicidade e na criatividade.
Parabens pelo artigo Fabio, estou com um projeto pra uma intranet e esse artigo com certeza será muito util.
ate mais
Leonardo França
[...] Veja o artigo completo: http://blog.dclick.com.br/2007/01/23/gerenciamento-de-memoria-e-tamanho-dos-arquivos-em-grandes-aplicativos-utilizando-o-modules-do-flex-201/ (No Ratings Yet) Loading … del.icio.us | digg! | furl | reddit | rojo | yahoo! | rec6 | dzone | Bloglines | Eu Curti [...]
Muito interessante essa abordagem Fabio, estava procurando algo assim e o seu post/exemplo caiu como uma luva. Parabéns !
Só não entendi uma coisa, o que vc quis dizer com compilar usando ‘dynamic linking’ ?
Nos testes que eu fiz aqui, compilei normalmente usando o ‘mxmlc.exe’ e funcionou também, vc vê algum problema ? Tem como configurar o flex builder para compilar e gerar esses arquivos separados ao invés de usar o prompt ?
Reparei que os arquivox mxml, deve ser do tipo ‘Module’, se fosse do tipo ‘Application’ funcionaria ? qual a diferença ?
valeu Fábio.
[]’s
mindu
Mindu,
Dynamic linking é um recurso para compilar o arquivo SWF com o mínimo de dependências possíveis, considerando que as demais dependências estarão presentes no arquivo que o carregou.
Assim, o seu Aplicativo.mxml já inclui uma série de componentes (por exemplo Panel, Label, TextInput, etc) que também serão utilizados por seu Modulo.mxml. Assim o Modulo.mxml, ao ser compilado, “externaliza” a dependência dessas classes para seu outro swf. O objetivo maior é otimizar e reduzir o tamanho dos arquivos.
Eles poderiam ser Applications se fossem utilizado em conjunto com o SWFLoader. O ModuleLoader é utilizado para carregar Modules, como no arquivo que disponibilizei. Teoricamente o efeito é o mesmo, mas o Modules é mais flexível para esse propósito específico de módulos de aplicativos.
[]s!
manual da memoria frex halloem
Bacana o artigo,
Será muito útil para aplicações posteriores e revisar algumas já feitas!
Meus Parabéns
Fabio muito interessante sua matéria sobre o consumo de memoria Parabéns .
Estou com uma duvida , seguinte fiz um modulo que implementa componentes que eu criei , na tag do modulo fica assim :
quando executo o mxmlc o compilador diz : Type was not found or was not a compile-time constant : COMBOC, eu vi no seu exemplo no aquivo build.mlx que tem parametros para o compilador , vc poderia me ajudar nesse problema ? desde já agredeço sua Atenção
Cool.
Cool.
Cool…
Cool.
Sorry ![]()
Cool!
Interesting…
Fábio, artigo muito interessante, com propriedade, foi muito útil para mim, parabéns e muito obrigado era exatamente o que eu estava procurando saber.
Esse artigo realmente me ajudou muito. Muito obrigado mesmo. Continuem evoluindo.
Após apreciar seu bom conhecimento, gostaria de aproveitar este espaço, para pedir um auxílio. Tenho um arquivo .fla, que ficou muito pesado, com 7,21 mb (megabites), e não conseguí mais abrí-lo de maneira alguma. Já aumentei a memória virtual, dentre várias outras tentativas. Há alguma meneita de conseguir abrir novamente o referido arquivo?
Abraços.
REPETIÇÃO DA MENSAGEM ANTERIOR, COM ENDEREÇO DE E-MAIL PARA CONTATO
Após apreciar seu bom conhecimento, gostaria de aproveitar este espaço, para pedir um auxílio. Tenho um arquivo .fla, que ficou muito pesado, com 7,21 mb (megabites), e não conseguí mais abrí-lo de maneira alguma. Já aumentei a memória virtual, dentre várias outras tentativas. Há alguma meneita de conseguir abrir novamente o referido arquivo?
Se souber, por favor, entre em contato: vanrafa2@yahoo.com.br
Abraços.
Excelente Fábio! Quem dera todos os artigos que a gente encontra por ai fossem completos como o seu!
Ótimo exemplo!!!
Porém, creio ter encontrado algo desfavorável no uso de módulos.
Gostaria de pedir a ajuda dos colegas para as 2 seguintes questões.
Primeira questão.
Vamos imaginar que estamos usando esse mesmo exemplo com gráficos,
porém,
a melhor prática seria que as “telas dos gráficos” fossem componentes “caixa-preta”, ou seja, que fizessem apenas a função de exibir valores, sem questionar a origem deles.
Num exemplo sem módulos, poderiamos fazer isso de forma simples,
usando uma “[Bindable] public var myModules:ArrayCollection=null;”
e deixarmos que o componente-pai cuidasse de preenchê-lo.
Porém, eu nunca encontrei uma forma de fazê-lo.
Algum dos colegas poderia me ajudar nesse ponto?
Segunda questão.
Vamos analisar uma estratégia simples de programar(sem módulos),
o Código funciona bem, vamos separar em componentes agora….
(espero não ter ido rápido demais…)
o que quero dizer é,
Como podemos levantar eventos entre o MX:MODULE e MX:MODULELOADER
Ótimo exemplo!!!
Porém, creio ter encontrado algo desfavorável no uso de módulos.
Gostaria de pedir a ajuda dos colegas para as 2 seguintes questões.
Primeira questão.
Vamos imaginar que estamos usando esse mesmo exemplo com gráficos,
porém,
a melhor prática seria que as “telas dos gráficos” fossem componentes “caixa-preta”, ou seja, que fizessem apenas a função de exibir valores, sem questionar a origem deles.
Num exemplo sem módulos, poderiamos fazer isso de forma simples,
usando uma “[Bindable] public var myModules:ArrayCollection=null;”
e deixarmos que o componente-pai cuidasse de preenchê-lo.
Porém, eu nunca encontrei uma forma de fazê-lo.
Algum dos colegas poderia me ajudar nesse ponto?
Segunda questão.
Vamos analisar uma estratégia simples de programar(sem módulos),
(mx:Application)
(mx:Script)
(![CDATA[
[Bindable] private var s:String=”texto”;
]])
(/mx:Script)
(mx:VBox)
(mx:Label id=”label1″ text={s}/)
(/mx:VBox)
(mx:HBox)
(mx:Button id=”bt1″ click=”texto=’modifiquei o texto’”/)
(/mx:HBox)
(/mx:Application)
o Código funciona bem, vamos separar em componentes agora….
(mx:Application)
(mx:Script)
(![CDATA[
[Bindable] private var s:String=”texto”;
]])
(/mx:Script)
(local:MeuVBox texto=”{s}”/)
(local:MeuHBox quandoClicou=”texto=(event as MeuEvento).s”)
(/mx:Application)
(espero não ter ido rápido demais…)
o que quero dizer é,
Como podemos levantar eventos entre o MX:MODULE e MX:MODULELOADER
Estou com esta mesma dúvida:
“Fabio muito interessante sua matéria sobre o consumo de memoria Parabéns .
Estou com uma duvida , seguinte fiz um modulo que implementa componentes que eu criei , na tag do modulo fica assim :
quando executo o mxmlc o compilador diz : Type was not found or was not a compile-time constant : COMBOC, eu vi no seu exemplo no aquivo build.mlx que tem parametros para o compilador , vc poderia me ajudar nesse problema ? desde já agredeço sua Atenção”
Olá Fabio,
Muito interessante o artigo. Tanto que adotei para um sistema que estou fazendo. Mesmo que o Flex 3 agora me possibilite chamar o garbage.
Mas a dúvida é a seguinte:
Antes eu usava o onCreationComplete para executar algo que eu gostaria que a aplicação executasse sempre na primeira vez que o módulo era acessado.
Como vc faz isso agora, ele só exeuta a primeira vez, se eu “fechar” (no meu caso posiciono o stack no item 0) e abrir, ele não vai mais chamar a função.
Existe algum outro evento? show, activate, etc..
Obrigado.
[...] http://blog.dclick.com.br/2007/01/23/gerenciamento-de-memoria-e-tamanho-dos-arquivos-em-grandes-apli... [...]
Estou aprendendo Flex a pouco tempo (1 semana) fiz uma pequena funcao p acompanhar o uso da memoria, nao sei se pode ser util para alguem, mas p mim esta sendo, pois posso acompanhar o comportamento da memoria, comforme vou navegando no projeto, nao sei se é a forma certa, qq coisa falem…
Notei q no Explorer o flex ocupa muito menos memoria, inicia com 5M e no FF o mesmo projeto inicia com 18M, sendo q o explorer esta com a versao 9.0.124 do player do flash e no FF a 9.0.115, entao esta diferenca pode ser (provavenmente) da versao do player e nao do navegador…
Colocar este campo de texto no projeto:
Colocar esta funcao no arquivo .as :
public function atualizaMem():void
{
var k:int = System.totalMemory / 1024;
var m:int = k / 1024;
mostraMemoria.text = String(k)+” Kb / ” + String(m)+” Mb”;
}

