Descarregando um ByteArray usando Actionscript 3

90

Como faço para descarregar à força um ByteArrayda memória usando o ActionScript 3?

Eu tentei o seguinte:

// First non-working solution
byteArray.length = 0;
byteArray = new ByteArray();

// Second non-working solution
for ( var i:int=0; i < byteArray.length; i++ ) {
    byteArray[i] = null;
}
Rann Lifshitz
fonte

Respostas:

34

Acho que você não tem nada com que se preocupar. Se System.totalMemorycair, você pode relaxar. Pode muito bem ser o sistema operacional que não recupera a memória recém-liberada (em antecipação à próxima vez que o Flash Player solicitará mais memória).

Tente fazer algo que exija muito da memória e tenho certeza de que você notará que a memória alocada para o Flash Player diminuirá e será usada para o outro processo.

Pelo que entendi, o gerenciamento de memória nos sistemas operacionais modernos não é intuitivo do ponto de vista de observar as quantidades alocadas para cada processo, ou mesmo a quantidade total alocada.

Quando eu uso meu Mac por 5 minutos, 95% dos meus 3 GB de RAM são usados ​​e ele permanecerá assim, nunca para de funcionar. É assim que o sistema operacional lida com a memória.

Desde que não seja necessário em outro lugar, mesmo os processos que foram encerrados ainda têm memória atribuída a eles (isso pode fazer com que sejam iniciados mais rapidamente na próxima vez, por exemplo).

Theo
fonte
24

(Não tenho certeza sobre isso, mas ...)

O AS3 usa uma coleta de lixo não determinística, o que significa que a memória não referenciada será liberada sempre que o tempo de execução desejar (normalmente, a menos que haja um motivo para executar, já que é uma operação cara). Esta é a mesma abordagem usada pela maioria das linguagens de coleta de lixo modernas (como C # e Java também).

Supondo que não haja outras referências à memória apontada por byteArrayou aos itens dentro do próprio array, a memória será liberada em algum ponto após você sair do escopo em que byteArrayfoi declarado.

Você pode forçar uma coleta de lixo, embora realmente não deva. Se você fizer isso, faça-o apenas para teste. Se você fizer isso na produção, irá prejudicar o desempenho muito mais do que ajudá-lo.

Para forçar um GC, tente (sim, duas vezes):

flash.system.System.gc();
flash.system.System.gc();

Você pode ler mais aqui .

Karl Seguin
fonte
19

Dê uma olhada neste artigo

http://www.gskinner.com/blog/archives/2006/06/as3_resource_ma.html

Programador de Actionscript IANA, no entanto, a sensação que estou tendo é que, porque o coletor de lixo pode não funcionar quando você quiser.

Portanto, http://www.craftymind.com/2008/04/09/kick-starting-the-garbage-collector-in-actionscript-3-with-air/

Portanto, eu recomendo experimentar o código de coleção e ver se ajuda

private var gcCount:int;
private function startGCCycle():void{
    gcCount = 0;
    addEventListener(Event.ENTER_FRAME, doGC);
}
private function doGC(evt:Event):void{
    flash.system.System.gc();
    if(++gcCount > 1){
        removeEventListener(Event.ENTER_FRAME, doGC);
        setTimeout(lastGC, 40);
    }
}
private function lastGC():void{
    flash.system.System.gc();
}
Jax
fonte
15

Infelizmente, quando se trata de gerenciamento de memória em Flash / Actionscript , não há muito que você possa fazer. O ActionScript foi projetado para ser fácil de usar (portanto, eles não queriam que as pessoas se preocupassem com o gerenciamento de memória)

A seguir está uma solução alternativa, em vez de criar uma ByteArrayvariável, tente isso.

var byteObject:Object = new Object();

byteObject.byteArray = new ByteArray();

...

//Then when you are finished delete the variable from byteObject
delete byteObject.byteArray;

Onde byteArrayestá uma propriedade dinâmica de byteObject, você pode liberar a memória que foi alocada para ela.

Barão Vermelho
fonte
15

Eu acredito que você respondeu sua própria pergunta.

System.totalMemoryfornece a quantidade total de memória sendo "usada", não alocada. É verdade que seu aplicativo pode estar usando apenas 20 MB, mas tem 5 MB que estão livres para alocações futuras.

Não tenho certeza se os documentos da Adobe esclareceriam a maneira como gerencia a memória.

Barão Vermelho
fonte
10

Portanto, se eu carregar, digamos, 20 MB do MySQL, no Gerenciador de Tarefas a RAM do aplicativo aumentará cerca de 25 MB. Então, quando eu fecho a conexão e tento descartar o ByteArray, a RAM nunca é liberada. No entanto, se eu usar System.totalMemory, o flash player mostra que a memória está sendo liberada, o que não é o caso.

O flash player está fazendo algo como Java e reservando espaço de heap e não o liberando até que o aplicativo feche?

Bem, sim e não, como você deve ter lido em incontáveis ​​posts de blog que o GC no AVM2 é otimista e funcionará de maneira misteriosa. Portanto, ele funciona um pouco como o Java e tenta reservar espaço de heap. No entanto, se você deixar isso por tempo suficiente e começar a fazer outras operações que estão consumindo uma quantidade significativa de memória, o espaço anterior será liberado. Você pode ver isso usando o criador de perfil durante a noite com alguns testes em execução no seu aplicativo.

Pedro
fonte
9

Portanto, se eu carregar, digamos, 20 MB do MySQL, no Gerenciador de Tarefas a RAM do aplicativo aumentará cerca de 25 MB. Então, quando eu fecho a conexão e tento descartar o ByteArray, a RAM nunca é liberada. No entanto, se eu usar System.totalMemory, o flash player mostra que a memória está sendo liberada, o que não é o caso.

O jogador está "liberando" a memória. Se você minimizar a janela e restaurá-la, verá que a memória agora está muito mais próxima do que System.totalMemory mostra.

Você também pode estar interessado em usar as ferramentas de perfil do FlexBuilder que podem mostrar se você realmente tem vazamentos de memória.


fonte