I was recently reading Nicolas’ most recent post on Flash 9 optimizations and I noticed that he had mentioned the use of an ‘Allocator’ class to help cut back on object instantiation. I actually have something along those lines in my personal framework, so I thought I would share it with you all.
First, a little bit about the subject. In an application in which you are constantly creating new objects, whether it be display objects or otherwise, you are going to suffer from a few different problems…
The first problem is performance. Creating new objects is somewhat slow, especially if their initialization process contains a lot of code. Performance is also affected by garbage collection. The more objects that are created, temporarily used, then left for garbage collection, the more that Flash Player has to work to clean up after your mess. This type of strain can be seen on the processor if you are monitoring processor load.
The second problem is memory. If you are constantly creating new objects for temporary use, the odds increase that you will screw up somewhere and things won’t get garbage collected properly. When this happens, it is called a memory leak. This is a pretty serious problem because potentially it could cause your application to crash along with the browser and maybe even the user’s machine.
You can cut back on these types of issues by simply keeping a close eye on your application piece by piece from the very beginning of development on a given project. Tools such as the Flex Builder profiler and the use of utilities such as ‘getTimer’ for timing chunks of code will help you a lot during this process. Depending on the complexity of your application, you may wish to take things a bit further to really help control the amount of new objects being created. That’s where my ‘Allocator’ class comes into play.
The ‘Allocator’ class is pretty simple; it’s composed of an array for caching objects, an index for tracking position within the cache, and a class type that the allocator instance is responsible for caching. Usage is pretty straightforward:
- // Create a new allocator instance.
- // The constructor argument is the class type
- // in which the allocator will handle caching for.
- // For the sake of example, I am working with a
- // class called 'MyModel'.
- var allocator:IAllocator = new Allocator(MyModel);
- // Get some instances of the MyModel class.
- // Since these are the first instances being
- // requested, they are being created and cached
- // before being returned.
- var modelA:MyModel = allocator.getObject();
- var modelB:MyModel = allocator.getObject();
- var modelC:MyModel = allocator.getObject();
- // Internally, this resets the cache index.
- // You do this once you have finished getting
- // a set of objects from the cache.
- // This time around, three MyModel instances
- // already exist in the cache, so no new objects
- // are created. The existing objects are re-used.
- modelA = allocator.getObject();
- modelB = allocator.getObject();
- modelC = allocator.getObject();
In practice, this type of workflow is ideal for a Flex application in which you are binded to data which is constantly changing. Rather than creating new model objects upon each data refresh, you create them once, then recycle each model object by passing the existing objects the new data. The sample files I have prepared for inclusion with the ‘Allocator’ source files demonstrate a basic model architecture that lends itself nicely to all of this.
Also worth noting is the performance numbers resulting from the included test file. The test runs two for-loops; the first one creates and caches the objects as the requests are made to the allocator for the first time. Next, the allocator is reset, then the second loop once again requests instances from the Allocator. Here are the results:
Initial -> Time: 0, Memory: 6815744
loop #1 -> Time: 20, Memory: 7467008
loop #2 -> Time: 22, Memory: 7467008
Notice that the first loop took 20 milliseconds and memory increased. The second loop only took 2 milliseconds and memory did not increase. Ten times the performance and no temporary memory increase is exactly why the Allocator is so useful.
Hopefully you will find this stuff useful in your projects. Feel free to share any questions or comments that you may have.7 comments