A Flash Developer Resource Site

Results 1 to 10 of 10

Thread: [RESOLVED] Remove or Reuse?

  1. #1
    Senior Member
    Join Date
    Jan 2006
    Posts
    133

    resolved [RESOLVED] Remove or Reuse?

    Hello All,

    I'm going to ask a VERY general question, is it "better" (in terms of resources, speed, memory, garbage collection) to remove objects or reuse them?

    It's my understanding that removing all references and "null"-ing an object makes it ELIGIBLE for garbage collection, but generally, without getting all work-around and hackish, there's no way to FORCE the object to get garbage collected.

    So, I was wondering would it just be "better" to re-use the object, instead of "deleting" the object when I know I will need another object just like it at some point in the future of the application?

  2. #2
    Mod cancerinform's Avatar
    Join Date
    Mar 2002
    Location
    press the picture...
    Posts
    13,449
    If you have a Loader and you load various images/movies of course reuse it. Regarding other objects it is not quite clear to me which objects you mean. Usually you remove objects when they are not needed any more when at the same you also create new objects like in a invader game.
    - The right of the People to create Flash movies shall not be infringed. -

  3. #3
    Senior Member
    Join Date
    Jan 2006
    Posts
    133
    Quote Originally Posted by cancerinform View Post
    If you have a Loader and you load various images/movies of course reuse it. Regarding other objects it is not quite clear to me which objects you mean. Usually you remove objects when they are not needed any more when at the same you also create new objects like in a invader game.
    Yeah, it's kind of an innocuous question/issue.
    But, the invader game is a perfect example.
    Let's say that creating a new invader is a "complex" process, i.e. maybe it involves adding listeners, positioning it, and just several setup steps.
    Once the invader is shot down, in order to remove the invader object, it may also take several "complex" steps... if you don't just want to rely on weak references etc.

    So, if this is how we create an Invader:

    Actionscript Code:
    // Create an invader
    var myInvader:Invader = new Invader();
    myInvader.addEventListener(Event.DESTROYED, onDestroyed, false, 0, true);
    ...
    myInvader.x = 0;
    myInvader.y = 0;
    ...
    addChild(myInvader);
    ...
    myInvader.attack();

    Then, if the Invader is destroyed, why should I remove the Invader and then create a brand new Invader like this:

    Actionscript Code:
    onDestroyed(e:Event):void{
        myInvader.removeListener(Event.DESTROYED, onDestroyed, false);
        ...
        ...
        removeChild(myInvader);
        myInvader = null;
    }

    // Add a new invader
    myInvader2:Invader = new Invader();
    myInvader2.addEventListener(Event.DESTROYED, onDestroyed, false, 0, true);
    ...
    myInvader2.x = 0;
    myInvader2.y = 0;
    ...
    addChild(myInvader2);
    ...
    myInvader2.attack();

    Instead of just reusing the 1st Invader like this:

    Actionscript Code:
    onDestroyed(e:Event):void{
       
        myInvader.visible = false;
        myInvader.x = 0;
        myInvader.y = 0;
        myInvader.visible = true;
        myInvader.attack();
       
    }

    The 1st example seems to have a greater chance of leaving superfluous listeners or references to the 1st Invader. Also, even if all references have been successfully removed, the 1st Invader is still going to hang out in memory until Flash is ready garbage collect.

    So, I was just wondering, since the 1st Invader is just sitting around waiting to be REALLY deleted, why not just reuse the 1st Invader object instead of creating a 2nd... thereby possibly introducing a situation where there are 2 invaders in memory, but only one is "active"?

    ps. In reality, I realize I wouldn't have to duplicate code every time I add an Invader, and there are better ways to write the code.
    But, for the purposes of this example, my question pertains to the concept/differences between removing an object (and all the necessary steps need to do so) and reusing an object.

  4. #4
    Senior Member
    Join Date
    Dec 2010
    Posts
    121
    You can have an identity variable as an uint that holds the number of myInvader. In the function onDestroyed, where you remove myInvader, you can find the number of myInvader and save that number in the identity variable and add 1. When adding a new invader, combine "myInvader" and the identity number variable to create a new instance, as if you are making new bullets using duplicateMovieClip.

  5. #5
    Will moderate for beer
    Join Date
    Apr 2007
    Location
    Austin, TX
    Posts
    6,801
    It is almost always more efficient to re-use an object rather than throw one away and build another just like it. The general principle at work here is an "object pool" and you can learn more by searching for that phrase.

    You do not need to do any of the identity number stuff that flashmed is suggesting, which seems to be aimed at creating a unique instance name for the instance. You don't need to give them names at all, so you don't need unique names. Instead, just put your instances in a collection like an Array or Vector. Maybe one collection for live instances and one for "reserve" instances, depending on what sort of processing you need to do on the live ones, and the expected ratio between live and inactive.

  6. #6
    Senior Member joshstrike's Avatar
    Join Date
    Jan 2001
    Location
    Alhama de Granada, España
    Posts
    1,131
    5Tons being right as usual, I just want to add that loading is the critical factor here, and be aware that if you're dealing with BitmapData objects, you have to copy them in order to safely use them in multiple Bitmaps. If that's the case, your pool should be "rolling" -- essentially a vector full of BitmapDatas that clone a new one on the end when one is requested and de-reference/empty/delete them when they aren't in use, keeping a buffer for a likely number to be created at one time so you don't see a freeze while the engine tries to duplicate and instantiate ten of them at once. How you actually implement this depends on the game, but the pool doesn't have to remain one size, and you need a method to actively prune it so that it doesn't just gobble memory.
    The Strike Agency
    http://www.theStrikeAgency.com

    StrikeSapphire -- The Original Bitcoin Casino
    https://strikesapphire.com
    (not available in the US)

  7. #7
    Ө_ө sleepy mod
    Join Date
    Mar 2003
    Location
    Oregon, USA
    Posts
    2,441
    Two more comments - first, I'm assuming this is similar to the classic space invaders where you will have a finite number of enemies (5 rows of 11 guys) - rather than destroying and creating new guys for every level or restart - just instantiate the max guys you'll need one time and "turn them off" when they're dead - this way your memory footprint is fixed. Obviously that's a pretty specific case but valuable if the conditions fit.

    Second - I ran some benchmarks a while back on the functions in the Point class - of the methods, roughly half of them operate on the existing Point object, the other half perform the math and return the results as a new Point object. The functions that allocate new points take about 13 times longer to execute than the in-place methods.
    Please use [php] or [code] tags, and mark your threads resolved 8)

  8. #8
    Senior Member
    Join Date
    Jan 2006
    Posts
    133
    Quote Originally Posted by 5TonsOfFlax View Post
    It is almost always more efficient to re-use an object rather than throw one away and build another just like it.
    Thanks, ActionScript abounds with exceptions, obviously... but in general, I was thinking this as well.

  9. #9
    Pumpkin Carving 2008 ImprisonedPride's Avatar
    Join Date
    Apr 2006
    Location
    Grand Rapids MI
    Posts
    2,379
    I realize this has already been resolved, but I just thought I could add my two cents for anyone finding this thread from the search.

    As has already been stated, it's generally a better idea to reuse common objects rather than creating a new one because of the overhead of memory involved. This is no more true than in Flash where memory is limited and optimization is a must.

    What I typically do for object pools is to create a "factory" class. This class usually has only a few members and methods:

    Members:
    • Private Array "pool" - Holds any objects not in use.
    • Private Array "active" - Holds any objects in use.


    Methods:
    • Public Function getObject() - Creates a new object if pool is empty; or returns an object spliced from the pool. Adds a reference to the returned object into the active array.
    • Public Function killObject(o:Object) - Returns Void. Finds this object in the active array, splices it out, and injects it back into the pool for use later (if the object class contains a "reset" method for reinitializing this object to default values, it is called here.


    A simple example:

    Code:
    public class BaddieFactory {
    
         private var pool:Array;
         private var active:Array;
    
         public BaddieFactory() {
              pool = [];
              active = [];
         }
    
         public getNewBaddie():Baddie {
              var b:Baddie;
              if (pool.length == 0) {
                   b = new Baddie();
              } else {
                   var b:Baddie = pool.pop();
              }
              active.push(b);
              return b;
         }
    
         public killBaddie(b:Baddie):void {
              b.nullify();
              for (var i:int = 0; i < active.length; i++) {
                   if (b == active[i]) {
                        pool.push(active.splice(i, 1));
                        break;
                   }
              }
         }
    
    }
    
    /*USAGE
    
            var bFactory = new BaddieFactory();
    
            var b:Baddie = bFactory.getNewBaddie();
            stage.addChild(b);
            b.goDoStuff();
    
            ...baddie dies...
    
            bFactory.killBaddie(b);
    
    */
    The 'Boose':
    ASUS Sabertooth P67 TUF
    Intel Core i7-2600K Quad-Core Sandy Bridge 3.4GHz Overclocked to 4.2GHz
    8GB G.Skill Ripjaws 1600 DDR3
    ASUS ENGTX550 TI DC/DI/1GD5 GeForce GTX 550 Ti (Fermi) 1GB 1GDDR5 (Overclocked to 1.1GHz)
    New addition: OCZ Vertex 240GB SATA III SSD
    WEI Score: 7.6

  10. #10
    Senior Member
    Join Date
    Jan 2006
    Posts
    133
    Quote Originally Posted by joshstrike View Post
    ... keeping a buffer for a likely number to be created at one time ...
    buffer?
    By this, do you mean storing 10 objects in the Vector and keeping them ready to go... even though most of the application will only need 1 or 2 of those objects at a time, but in a specific state the App might need 10 at once?

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  




Click Here to Expand Forum to Full Width

HTML5 Development Center