Descarga de un ByteArray con Actionscript 3

91

¿Cómo descargo a la fuerza un ByteArrayde la memoria con ActionScript 3?

He probado lo siguiente:

// 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
fuente

Respuestas:

35

No creo que tengas nada de qué preocuparte. Si System.totalMemorybaja puedes relajarte. Es muy posible que sea el sistema operativo el que no recupere la memoria recién liberada (en previsión de la próxima vez que Flash Player solicite más memoria).

Intente hacer otra cosa que consuma mucha memoria y estoy seguro de que notará que la memoria asignada a Flash Player disminuirá y se utilizará para el otro proceso.

Como lo he entendido, la gestión de la memoria en los sistemas operativos modernos no es intuitiva desde la perspectiva de mirar las cantidades asignadas a cada proceso, o incluso la cantidad total asignada.

Cuando he usado mi Mac durante 5 minutos, se usa el 95% de mis 3 GB de RAM, y permanecerá así, nunca se apaga. Esa es la forma en que el sistema operativo maneja la memoria.

Siempre que no sea necesario en otro lugar, incluso los procesos que se han cerrado todavía tienen memoria asignada (esto puede hacer que se inicien más rápido la próxima vez, por ejemplo).

Theo
fuente
25

(No estoy seguro de esto, pero ...)

AS3 utiliza una recolección de basura no determinista, lo que significa que la memoria desreferenciada se liberará cuando el tiempo de ejecución lo considere oportuno (por lo general, no a menos que haya una razón para ejecutarlo, ya que es una operación costosa de ejecutar). Este es el mismo enfoque utilizado por la mayoría de los lenguajes de recolección de basura modernos (como C # y Java también).

Suponiendo que no hay otras referencias a la memoria apuntada por byteArrayo los elementos dentro de la propia matriz, la memoria se liberará en algún momento después de que salga del alcance donde byteArrayse declara.

Puede forzar una recolección de basura, aunque no debería hacerlo. Si lo hace, hágalo solo para probar. Si lo hace en producción, perjudicará el rendimiento mucho más que lo ayudará.

Para forzar un GC, intente (sí, dos veces):

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

Puedes leer más aquí .

Karl Seguin
fuente
20

Mira este artículo

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

Programador de actionscript de IANA, sin embargo, la sensación que tengo es que, porque es posible que el recolector de basura no se ejecute cuando lo desee.

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

Así que recomiendo probar su código de colección y ver si ayuda

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
fuente
16

Desafortunadamente, cuando se trata de la administración de memoria en Flash / actionscript, no hay mucho que pueda hacer. ActionScript fue diseñado para ser fácil de usar (por lo que no querían que la gente tuviera que preocuparse por la gestión de la memoria)

La siguiente es una solución alternativa, en lugar de crear una ByteArrayvariable, intente esto.

var byteObject:Object = new Object();

byteObject.byteArray = new ByteArray();

...

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

Donde byteArrayhay una propiedad dinámica de byteObject, puede liberar la memoria que se le asignó.

Barón Rojo
fuente
16

Creo que ha respondido a su propia pregunta.

System.totalMemoryle da la cantidad total de memoria que se "utiliza", no asignada. Es cierto que su aplicación solo puede usar 20 MB, pero tiene 5 MB libres para futuras asignaciones.

No estoy seguro de si los documentos de Adobe arrojarían luz sobre la forma en que administra la memoria.

Barón Rojo
fuente
11

Entonces, si cargo, digamos, 20 MB de MySQL, en el Administrador de tareas, la RAM de la aplicación aumenta en aproximadamente 25 MB. Luego, cuando cierro la conexión e intento deshacerme del ByteArray, la RAM nunca se libera. Sin embargo, si utilizo System.totalMemory, el reproductor flash muestra que la memoria se está liberando, lo que no es el caso.

¿El reproductor flash está haciendo algo como Java, reservando espacio en el montón y no lo libera hasta que se cierra la aplicación?

Bueno, sí y no, ya que puede haber leído en innumerables publicaciones de blog que el GC en AVM2 es optimista y funcionará de manera misteriosa. Así que funciona un poco como Java e intenta reservar espacio en el montón. Sin embargo, si lo dejas lo suficiente y comienzas a realizar otras operaciones que consumen una cantidad significativa de memoria, liberará ese espacio anterior. Puede ver esto usando el generador de perfiles durante la noche con algunas pruebas ejecutándose en la parte superior de su aplicación.

Pedro
fuente
10

Entonces, si cargo, digamos, 20 MB de MySQL, en el Administrador de tareas, la RAM de la aplicación aumenta en aproximadamente 25 MB. Luego, cuando cierro la conexión e intento deshacerme del ByteArray, la RAM nunca se libera. Sin embargo, si utilizo System.totalMemory, el reproductor flash muestra que la memoria se está liberando, lo que no es el caso.

El jugador está "liberando" la memoria. Si minimiza la ventana y la restaura, debería ver que la memoria ahora está mucho más cerca de lo que muestra System.totalMemory.

También podría estar interesado en utilizar las herramientas de creación de perfiles de FlexBuilder que pueden mostrarle si realmente tiene pérdidas de memoria.


fuente