Search code examples
actionscript-3flashmemoryactionscriptfilereference

How to free memory after use of FileRerence?


See [Solution]


FileReference.load(); does not have a function to unload, just as there is new Loader ().unload();.

Must be a "BUG" from Flash or FileReference needs improvement, type in a new version add a function like this: FileReference.unload();

Or am I mistaken and exists a SOLUTION?

I tried to set "NULL" to a variable of type FileReference, but clearly this does not work for the Flash works with GC (garbage collector), but this is not the focus of the question.

The problem is that a lot of memory when loading multiple files with new FileReferenceList is necessary, but I can not free memory after the process.

How to free memory after use of FileRerence?

See my code:

Main.as

package {
     import com.mainpackage.LoaderTestCase;

     import flash.net.FileReferenceList;
     import flash.net.FileReference;
     import flash.net.FileFilter;
     import flash.events.Event;
     import flash.display.MovieClip;

     public class Main extends MovieClip {
          private var listFiles:Array;
          private var allTypes:Array;
          private var fileRef:FileReferenceList;
          private var test:int;

          public function Main()
          {
               test = 0;
               listFiles     = [];
               allTypes     = [];
               fileRef          = new FileReferenceList();
               fileRef.addEventListener(Event.SELECT, select);

               fileRef.browse(allTypes);
          }

          private function select(e:Event):void
          {
               listFiles = fileRef.fileList;

               for(var i:uint=0, j:uint=listFiles.length; i<j; i++)
               {
                    insert(i);
               }
          }

          private function insert(c:int):void
          {
               var fire:LoaderTestCase = new LoaderTestCase(listFiles[c]);

               fire.destroy(function():void
               {
                    //Delete LoaderTestCase after timeout ???
                    fire = null;
                    test++;
                    if(test>=listFiles.length) {//Remove FileReference
                         fileRef.removeEventListener(Event.SELECT, select);
                         fileRef = null;

                         for(var i:uint=0, j:uint=listFiles.length; i<j; i++) {
                              listFiles[i] = null;
                         }
                         listFiles = null;

                         trace("Clear memory");
                    }
               });
          }
     }
}

LoaderTestCase.as

package com.mainpackage
{
    import flash.net.FileReference;
    import flash.events.Event;
    import flash.display.Loader;

    public class LoaderTestCase
    {
        private var file:FileReference;
        private var loader:Loader;
        private var callback:Function;

        public function LoaderTestCase(e:FileReference)
        {
            file = e;
            trace("OPEN: " + file.name);
            file.addEventListener(Event.COMPLETE, loadFile);
            file.load();
            e = null;
        }

        public function loadFile(e:Event):void
        {
            file.removeEventListener(Event.COMPLETE, loadFile);

            trace("LOAD: " + file.name);

            file    = null;
            e       = null;
            callback();
        }

        public function destroy(a:Function):void
        {
            callback = a;
        }
    }
}

Solution

  • I reached my goal, if I so did FileReferenceList.fileList[5] = null; (when the "sixth file" is not being used more) Flash memory immediately frees this specific FileReference.

    In the others words:

    This not work:

    private var file:FileReference;
    ...
    file = FileReferenceList.fileList[5];
    ...
    file = null;
    

    But this worked:

    FileReferenceList.fileList[5] = null;
    

    Worked on all Desktop/Plugins/PepperFlash.

    See worked code:

    package {
        import flash.net.FileReferenceList;
        import flash.net.FileReference;
        import flash.net.FileFilter;
        import flash.events.MouseEvent;
        import flash.events.Event;
        import flash.display.Sprite;
    
        public class Main extends Sprite
        {
            private var listFiles:Array;
            private var allTypes:Array;
            private var fileRef:FileReferenceList;
            private var tmpFile:FileReference;
            private var i:uint=0;
            private var j:uint=0;
            private var timer:uint;
            private var imageTypes:FileFilter;
            private var enable:Boolean;
    
            public function Main()
            {
                imageTypes   = new FileFilter(
                    "Images (*.JPG;*.JPEG;*.JPE;)", "*.jpg; *.jpeg; *.jpe;"
                );
                listFiles   = [];
                allTypes    = [imageTypes];
    
                eventBrowse(true);
            }
    
            private function eventBrowse(a:Boolean):void
            {
                enable = a;
                if(a===true) {
                    stage.addEventListener(MouseEvent.CLICK, browse);
    
                    fileRef = new FileReferenceList();
                    fileRef.addEventListener(Event.SELECT, select);
                } else {
                    fileRef.removeEventListener(Event.SELECT, select);
                    fileRef = null;
    
                    stage.removeEventListener(MouseEvent.CLICK, browse);
                }
            }
    
            private function browse(e:MouseEvent):void
            {
                if(enable===true) {
                    fileRef.browse(allTypes);
                }
            }
    
            private function select(e:Event):void
            {
                listFiles = fileRef.fileList;
    
                eventBrowse(false);
    
                i=0;
                j=listFiles.length;
    
                if(j>0) {
                    loadNextFile();
                }
            }
    
            private function loadNextFile():void
            {
                if(!(i<j)) {
                    listFiles = null;
                    trace("Free memory???");
                    trace("--------------");
                    trace("listFiles:"+ listFiles);
                    trace("allTypes:" + allTypes);
                    trace("fileRef:" + fileRef);
                    trace("tmpFile:" + tmpFile);
                    trace("i:" + i);
                    trace("j:" + j);
                    trace("timer:" + timer);
                    trace("--------------");
                    eventBrowse(true);
                    return;
                }
    
                tmpFile = listFiles[i];
                trace("Initiate load:" + tmpFile.name);
                tmpFile.addEventListener(Event.COMPLETE, loadedFile);
                tmpFile.load();
            }
    
            private function loadedFile(f:Event):void
            {
                trace(listFiles);
                trace("Finished load:" + tmpFile.name);
                tmpFile.removeEventListener(Event.COMPLETE, loadedFile);
    
                tmpFile = null;
                listFiles[i] = null;
    
                i++;
                loadNextFile();
            }
        }
    }