Déchargement d'un ByteArray à l'aide d'Actionscript 3

90

Comment décharger de force un ByteArrayde la mémoire à l'aide d'ActionScript 3?

J'ai essayé ce qui suit:

// 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
la source

Réponses:

34

Je ne pense pas que vous ayez à vous inquiéter. Si System.totalMemorydescend, vous pouvez vous détendre. Il se peut très bien que le système d'exploitation ne récupère pas la mémoire nouvellement libérée (en prévision de la prochaine fois que Flash Player demandera plus de mémoire).

Essayez de faire autre chose qui demande beaucoup de mémoire et je suis sûr que vous remarquerez que la mémoire allouée à Flash Player diminuera et sera utilisée pour l'autre processus à la place.

Comme je l'ai compris, la gestion de la mémoire dans les systèmes d'exploitation modernes n'est pas intuitive du point de vue des montants alloués à chaque processus, ou même du montant total alloué.

Lorsque j'utilise mon Mac pendant 5 minutes, 95% de ma RAM de 3 Go est utilisée, et cela restera ainsi, il ne tombera jamais en panne. C'est juste la façon dont le système d'exploitation gère la mémoire.

Tant que cela n'est pas nécessaire ailleurs, même les processus qui ont quitté ont encore de la mémoire qui leur est attribuée (cela peut les faire démarrer plus rapidement la prochaine fois, par exemple).

Théo
la source
24

(Je ne suis pas sûr de ça, mais ...)

AS3 utilise un garbage collection non déterministe, ce qui signifie que la mémoire déréférencée sera libérée chaque fois que le runtime en a envie (généralement pas à moins qu'il n'y ait une raison de s'exécuter, car c'est une opération coûteuse à exécuter). Il s'agit de la même approche utilisée par la plupart des langages de récupération de place modernes (comme C # et Java également).

En supposant qu'il n'y ait aucune autre référence à la mémoire pointée par byteArrayou aux éléments du tableau lui-même, la mémoire sera libérée à un moment donné après que vous ayez quitté la portée où byteArrayest déclaré.

Vous pouvez forcer un garbage collection, bien que vous ne devriez vraiment pas. Si vous le faites, faites-le uniquement pour les tests. Si vous le faites en production, vous nuirez bien plus aux performances que vous ne les aiderez.

Pour forcer un GC, essayez (oui, deux fois):

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

Vous pouvez en savoir plus ici .

Karl Seguin
la source
19

Jetez un œil à cet article

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

Programmeur d'actionscript IANA, mais le sentiment que j'éprouve est le suivant, car le ramasse-miettes peut ne pas fonctionner quand vous le souhaitez.

D'où http://www.craftymind.com/2008/04/09/kick-starting-the-garbage-collector-in-actionscript-3-with-air/

Je vous recommande donc d'essayer leur code de collection et de voir si cela aide

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
la source
15

Malheureusement, en ce qui concerne la gestion de la mémoire dans Flash / actionscript , vous ne pouvez pas faire grand chose. ActionScript a été conçu pour être facile à utiliser (ils ne voulaient donc pas que les gens aient à se soucier de la gestion de la mémoire)

Voici une solution de contournement, au lieu de créer une ByteArrayvariable, essayez ceci.

var byteObject:Object = new Object();

byteObject.byteArray = new ByteArray();

...

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

byteArrayest une propriété dynamique de byteObject, vous pouvez libérer la mémoire qui lui a été allouée.

Baron Rouge
la source
15

Je pense que vous avez répondu à votre propre question.

System.totalMemoryvous donne la quantité totale de mémoire "utilisée", non allouée. Il est exact que votre application n'utilise que 20 Mo, mais elle dispose de 5 Mo qui sont gratuits pour les allocations futures.

Je ne suis pas sûr que les documents Adobe éclairent la manière dont il gère la mémoire.

Baron Rouge
la source
10

Donc, si je charge disons 20 Mo de MySQL, dans le gestionnaire de tâches, la RAM de l'application augmente d'environ 25 Mo. Ensuite, lorsque je ferme la connexion et que j'essaye de supprimer ByteArray, la RAM ne se libère jamais. Cependant, si j'utilise System.totalMemory, flash player montre que la mémoire est libérée, ce qui n'est pas le cas.

Le lecteur Flash fait-il quelque chose comme Java et réserve de l'espace sur le tas et ne le libère-t-il pas tant que l'application ne se ferme pas?

Eh bien oui et non, comme vous l'avez peut-être lu dans d'innombrables articles de blog, le GC dans AVM2 est optimiste et fonctionnera de ses propres manières mystérieuses. Cela fonctionne donc un peu comme Java et tente de réserver de l'espace sur le tas. Cependant, si vous laissez suffisamment de temps et commencez à effectuer d'autres opérations qui consomment beaucoup de mémoire, cela libérera cet espace précédent. Vous pouvez le voir en utilisant le profileur pendant la nuit avec quelques tests exécutés au-dessus de votre application.

Pedro
la source
9

Donc, si je charge disons 20 Mo de MySQL, dans le gestionnaire de tâches, la RAM de l'application augmente d'environ 25 Mo. Ensuite, lorsque je ferme la connexion et que j'essaye de supprimer ByteArray, la RAM ne se libère jamais. Cependant, si j'utilise System.totalMemory, flash player montre que la mémoire est libérée, ce qui n'est pas le cas.

Le joueur «libère» la mémoire. Si vous minimisez la fenêtre et la restaurez, vous devriez voir que le memeory est maintenant beaucoup plus proche de ce que System.totalMemory montre.

Vous pourriez également être intéressé par l'utilisation des outils de profilage de FlexBuilder qui peuvent vous montrer si vous avez vraiment des fuites de mémoire.


la source