The Size of Empty
I was reminded about the flash.sampler API by Grant Skinner’s recent post about it. While only available in the debug player, it can still tell us some valuable information about what goes on in the release player. Today I’m using the getSize function to find out how much memory overhead various classes impose, even when they are empty.
getSize is a simple function. All you do is pass in an object and it will return the size of it in bytes. So I tried making a lot of “empty” objects (eg. Array, Dictionary) and threw in a couple of basics (eg. int, Number) just for good measure. The test was extremely straightforward:
package { import flash.display.*; import flash.events.*; import flash.geom.*; import flash.sampler.*; import flash.system.*; import flash.text.*; import flash.xml.*; import flash.utils.*; public class SizeOfEmpty extends Sprite { public function SizeOfEmpty() { var logger:TextField = new TextField(); logger.autoSize = TextFieldAutoSize.LEFT; logger.defaultTextFormat = new TextFormat("_typewriter", 8); addChild(logger); if (!Capabilities.isDebugger) { logger.text = "Debug player is required to run this tool"; } else { logger.text = "Object: " + getSize(new Object()) + "\n" + "Array: " + getSize(new Array()) + "\n" + "Vector.<int>: " + getSize(new Vector.<int>()) + "\n" + "Vector.<uint>: " + getSize(new Vector.<uint>()) + "\n" + "Vector.<Number>: " + getSize(new Vector.<Number>()) + "\n" + "Vector.<Object>: " + getSize(new Vector.<Object>()) + "\n" + "ByteArray: " + getSize(new ByteArray()) + "\n" + "Dictionary: " + getSize(new Dictionary()) + "\n" + "String: " + getSize(new String("")) + "\n" + "Class Instance: " + getSize(new EmptyClass()) + "\n" + "Dynamic Function: " + getSize(function():void{}) + "\n" + "Instance Method: " + getSize(instanceMethod) + "\n" + "Static Method: " + getSize(staticMethod) + "\n" + "BitmapData: " + getSize(new BitmapData(1, 1, true)) + "\n" + "EventDispatcher: " + getSize(new EventDispatcher()) + "\n" + "Sprite: " + getSize(new Sprite()) + "\n" + "MovieClip: " + getSize(new MovieClip()) + "\n" + "TextField: " + getSize(new TextField()) + "\n" + "Shape: " + getSize(new Shape()) + "\n" + "Loader: " + getSize(new Loader()) + "\n" + "Error: " + getSize(new Error()) + "\n" + "Event: " + getSize(new Event("")) + "\n" + "XML: " + getSize(new XML()) + "\n" + "XMLNode: " + getSize(new XMLNode(1, "")) + "\n" + "RegExp: " + getSize(new RegExp()) + "\n" + "Matrix: " + getSize(new Matrix()) + "\n" + "Matrix3D: " + getSize(new Matrix3D()) + "\n" + "Vector3D: " + getSize(new Vector3D()) + "\n" + "Point: " + getSize(new Point()) + "\n" + "Rectangle: " + getSize(new Rectangle()) + "\n" + "Timer: " + getSize(new Timer(1)) + "\n" + "Namespace: " + getSize(new Namespace()) + "\n" + "Boolean: " + getSize(new Boolean(true)) + "\n" + "int: " + getSize(new int(44)) + "\n" + "uint: " + getSize(new uint(44)) + "\n" + "Number: " + getSize(new Number(44.0)) + "\n"; } } private function instanceMethod(): void {} private static function staticMethod(): void {} } } class EmptyClass {}
I then ran it in the latest debug player in Firefox on Windows XP and got these results:
Type | Size (in bytes) |
---|---|
Object | 24 |
Array | 40 |
Vector.<int> | 48 |
Vector.<uint> | 48 |
Vector.<Number> | 48 |
Vector.<Object> | 56 |
ByteArray | 80 |
Dictionary | 32 |
String | 28 |
Class Instance | 8 |
Dynamic Function | 666 |
Instance Method | 32 |
Static Method | 32 |
BitmapData | 68 (includes 4 bytes for the single pixel) |
EventDispatcher | 56 |
Sprite | 420 |
MovieClip | 452 |
TextField | 1096 |
Shape | 248 |
Loader | 320 |
Error | 44 |
Event | 32 |
XML | 16 |
XMLNode | 48 |
RegExp | 48 |
Matrix | 56 |
Matrix3D | 80 |
Vector3D | 40 |
Point | 24 |
Rectangle | 40 |
Timer | 88 |
Namespace | 8 |
Boolean | 4 |
int | 4 |
uint | 4 |
Number | 4 |
And here they are in graph form:
There are some interesting finds here:
- Number (an 8-byte floating-point value), Boolean (a single bit of data), int (a 4-byte signed integer), and uint (a 4-byte unsigned integer) all take up 4 bytes of memory. This likely means that they are all actually pointers to the actual data or that 4 bytes is some kind of minimum. (UPDATE: This is related to Flash Player storing some values as an integer. For more, see the article What is an int?.)
- Dynamic functions are much more memory-intensive than methods, static or not. If you’re trying to save some memory, perhaps due to the constraints of a mobile device, you should make sure you don’t have a lot of these around. This may be the case if you use them as callbacks for many UI elements such as click handling for every item in a big list.
- TextFields use over 1 KB of memory. While it’s unlikely that you’d have more than a handful on screen at once, consider all the ones that may be hidden. If you use MovieClips for each button state (up, over, down, etc.) and each has a TextField label, this may quickly add up. Also, it’s common to have all the screens of a UI in memory at once so beware of all the TextFields you have have around that are simply set to invisible or are not currently on the stage.
- MovieClip uses only slightly more memory than Sprite, a relief
- Shape uses far less memory than Sprite, which reinforces why you might like to use it instead of Sprite.
- If you don’t need weak references and care more about memory savings than syntax benefits, consider Object over Dictionary for your mapping needs if you use a lot of them.
Overall I would say that the Flash Player is reasonably-efficient with memory usage for empty objects. Only in niche cases will you ever be called upon to reduce memory usage by reducing your data structure overhead, but those cases do exist. The size of an object can become very important when you’re storing tens of thousands of them for 3D meshes, targeting a tiny mobile device, or just trying to push the limits on a desktop machine.
#1 by jpauclair on April 20th, 2010 ·
Very useful info!
Maybee you can add Bitmap to these?
#2 by jackson on April 20th, 2010 ·
Bitmap: 248
If I get enough suggestions here in the comments I will update the article with new code, results table, and graph.
#3 by Fardeen on April 21st, 2010 ·
Thx !
I’m happy to see there is no real difference btw Sprite and MovieClip.
#4 by Eugene on April 27th, 2010 ·
Number (an 8-byte floating-point value)
Number in flash is Double actually. thats why it takes 8 bytes.
#5 by jackson on April 27th, 2010 ·
“Double” is just short for “double-precision floating-point“.
#6 by Eugene on April 29th, 2010 ·
Ah yes! ;)
just make a note… sure u know it!)
#7 by derek knox on September 22nd, 2010 ·
Very useful and a very great idea to create a graph. I’ll use the graph as a reference until I know it well enough. Good idea.
#8 by Geo on October 24th, 2010 ·
Hi,
can you do examples of:
– button,
– mx:Image;
– Effects;
– Windowed Application vs Sprite;
– mx:Image vs s:BitmapImage;
– Bitmap;
it would be very helpful. :)
#9 by jackson on October 24th, 2010 ·
I try to stick to the Flash Player’s built-in classes, so
Button
,mx:Image
,BitmapImage
, and presumablyEffects
would fall outside this scope. I’m also not sure what you mean by a “Windowed Application”. Do you mean the overhead of AIR as opposed to the plugin or ActiveX control?Bitmap
is definitely in the Flash Player core, but it can’t really be “empty” or “full” since it always just contains a singleBitmapData
.#10 by Chris on August 25th, 2011 ·
It is possible that Number optimizes its space based on the initial value.
This may explain why your getSize(Number) only returned 4 bytes (vs. the expected 8).
I got the following results on my system:
gives this in the debugger:
#11 by jackson on August 25th, 2011 ·
I’ve updated the article for that conclusion point to reflect some newfound knowledge about the nature of
Number
andint
.#12 by dimpiax on January 10th, 2014 ·
FlashPlayer 11.9.900.117
OS X 10.9.1
#13 by jackson on January 10th, 2014 ·
Thanks for posting your results. It looks like many of these have increased in size since I posted my results. This may be due to the use of a 64-bit Flash Player where pointers (i.e. memory addresses, references) use 64 bits rather than the 32 bits in older players.