Skip to main content
Known Participant
October 29, 2012
Respondido

How to garbage collect an newed as3 Sound Object from memory?

  • October 29, 2012
  • 1 resposta
  • 6476 Visualizações

For example, using next text code:

 

package

{

          import flash.display.*;

          import flash.events.*;

          import flash.media.*;

          import flash.system.*;

          import flash.system.*;

 

          public class Main extends Sprite

          {

                    [Embed(source = "../data/SongScene8.mp3")] protected var SongScene8:Class;

 

                    public function Main():void

                    {

                              if (stage) init();

                              else addEventListener(Event.ADDED_TO_STAGE, init);

                    }

 

                    private function init(e:Event = null):void

                    {

                              removeEventListener(Event.ADDED_TO_STAGE, init);

 

                              System.gc();

                              trace("Before");

                              trace(System.totalMemory);

                              trace("_________________")

 

                              var sound:Sound = new SongScene8();

                              System.gc();

                              trace("After new");

                              trace(System.totalMemory);

                              trace("_________________")

 

                              sound = null;

                              System.gc();

                              trace("After null");

                              trace(System.totalMemory);

                    }

          }

 

}

The output is:

Before

3461120

_________________

After new

3604480

_________________

After null

3604480

* Even if the gc runs a thousand times after, the last, increased value remains.

* I've tested this too by importing an mp3 from an .swc, rather than from a file. The result is similar.

* Tracing System.privateMemory rather than System.totalMemory gives similar (although offset) results.

Wether or not a soundchannel is played on it, it looks like the Sound Object

cannot be removed from memory.

 

Please say I'm wrong and tell me why.

Thanks in advance

Este tópico foi fechado para respostas.
Melhor resposta por sinious

.. and I've just tested as well on Flash Pro Cs6, version 12.0.0.481, flex 4.0.0
with similar results.


Flash can tell the OS it doesn't need the memory but memory management goes well beyond Flash itself. The OS dictates when app cache allocations are removed and reported as non-commit and available. It's in the OS's best interest to always keep recently loaded resources around until resources become scarce. On a desktop, especially for your simple test, the OS is in absolutely no rush to flush that cache. They call it "System".gc() because it's not "Flash".gc(). Flash has let the resources go, it's up to the OS to then clear the cache at its own desire.

This is also only available in certain circumstances, API:

For the Flash Player debugger version and AIR applications only. In an AIR application, the System.gc() method is only enabled in content running in the AIR Debug Launcher (ADL) or, in an installed applcation, in content in the application security sandbox.

It's just as likely that nulling the var will cause the memory to release as calling System.gc() if resources are low. Ultimately there's no real need on a desktop so it stalls. You'd see a much faster collection response whether you call System.gc() or not on a device once an object is properly dereferenced.

1 Resposta

kglad
Community Expert
Community Expert
October 30, 2012

you're wrong.

you need to execute your System.gc() 2 or 3 times, each time separated by a time tick.  ie, use something like:

var n:int;

function clearF():void{

     n=0;

     this.addEventListener(Event.ENTER_FRAME,f);

}

function f(e:Event):void{

    System.gc();

    trace("After null");

    trace(System.totalMemory);

     n++;

     if(n>3){

          this.removeEventListener(Event.ENTER_FRAME,f);

     }

}

Known Participant
October 30, 2012

I wish you were right, kglad, but if I apply your code example (with n>10), I get the output as is listed below.
As it appears, even if the garbage collector is called on thousands of frame events, the leak remains.

I still hope I'm wrong - I must be - or I should have been able to find other questions from people about this ostensible leak.

I'm still hoping someone can tell me why.

Before

3465216

_________________

After new

3608576

_________________

After null

4206592

After null

4194304

After null

4194304

After null

4194304

After null

4194304

After null

4194304

After null

4194304

After null

4194304

After null

4194304

After null

4194304

After null

4194304

kglad
Community Expert
Community Expert
October 30, 2012

what flash cs version are you testing on?