flash.sampler.getSize() is a handy tool for figuring out how much memory a class instance uses. However, it is often flat-out wrong. Today’s article tries it out on a variety of classes to find out which ones it works on and which ones it doesn’t.

The following test app creates two instances of each class. The first is designed to be as close to an “empty” version as possible. For example, an Array with no elements. The second is designed to be big enough that getSize would tell us it’s bigger. For example, an Array with 9 elements.

The following classes were tested:

  • XML
  • String
  • Object
  • Vector
  • Array
  • RegExp
  • BitmapData
  • IndexBuffer3D
  • VertexBuffer3D
  • Texture

Here’s the source code for the test app:

package
{
	import flash.display.*;
	import flash.display3D.*;
	import flash.display3D.textures.*;
	import flash.utils.*;
	import flash.text.*;
	import flash.sampler.*;
	import flash.events.*;
	import flash.system.*;
 
	public class GetWrongSize extends Sprite
	{
		private var logger:TextField = new TextField();
		private function row(...cols): void
		{
			logger.appendText(cols.join(",") + "\n");
		}
 
		public function GetWrongSize()
		{
			stage.align = StageAlign.TOP_LEFT;
			stage.scaleMode = StageScaleMode.NO_SCALE;
 
			logger.autoSize = TextFieldAutoSize.LEFT;
			addChild(logger);
 
			if (!Capabilities.isDebugger)
			{
				row("This app requires a debug Player");
				return;
			}
 
			var stage3D:Stage3D = stage.stage3Ds[0];
			stage3D.addEventListener(Event.CONTEXT3D_CREATE, onContext3D);
			stage3D.requestContext3D();
		}
 
		private function onContext3D(ev:Event): void
		{
			var stage3D:Stage3D = stage.stage3Ds[0];
			var context3D:Context3D = stage3D.context3D;
 
			var xmlEmpty:XML = new XML();
			var xml:XML = <xml><something/><stuff/><things/><more/><data/></xml>;
 
			var strEmpty:String = "";
			var str:String = "abunchoftextisinthisstringandnowthereisevenmore";
 
			var objEmpty:Object = {};
			var obj:Object = { key:123, thing:456, stuff:789, other:000 };
 
			var vecEmpty:Vector.<int> = new <int>[];
			var vec:Vector.<int> = new <int>[123,456,789,000,111,222,333,444,555];
 
			var arrEmpty:Array = [];
			var arr:Array = [123,456,789,000,111,222,333,444,555];
 
			var regexEmpty:RegExp = new RegExp("");
			var regex:RegExp = new RegExp("[abcdefghijklmnopqrstuvwxyz0123456789]");
 
			var bmdEmpty:BitmapData = new BitmapData(1, 1);
			var bmd:BitmapData = new BitmapData(64, 64);
 
			var ibEmpty:IndexBuffer3D = context3D.createIndexBuffer(1);
			var ib:IndexBuffer3D = context3D.createIndexBuffer(1024);
 
			var vbEmpty:VertexBuffer3D = context3D.createVertexBuffer(1, 4);
			var vb:VertexBuffer3D = context3D.createVertexBuffer(1024, 4);
 
			var texEmpty:Texture = context3D.createTexture(bmdEmpty.width, bmdEmpty.height, "bgra", false);
			var tex:Texture = context3D.createTexture(bmd.width, bmd.height, "bgra", false);
			texEmpty.uploadFromBitmapData(bmdEmpty);
			tex.uploadFromBitmapData(bmd);
 
			row("Object", "Empty Size", "Size");
			row("XML", getSize(xmlEmpty), getSize(xml));
			row("String", getSize(strEmpty), getSize(str));
			row("Object", getSize(objEmpty), getSize(obj));
			row("Vector", getSize(vecEmpty), getSize(vec));
			row("Array", getSize(arrEmpty), getSize(arr));
			row("RegExp", getSize(regexEmpty), getSize(regex));
			row("BitmapData", getSize(bmdEmpty), getSize(bmd));
			row("IndexBuffer3D", getSize(ibEmpty), getSize(ib));
			row("VertexBuffer3D", getSize(vbEmpty), getSize(vb));
			row("Texture", getSize(texEmpty), getSize(tex));
		}
	}
}

And here are the results:

Object Empty Size Size
XML 120 608
String 40 40
Object 80 176
Vector 144 160
Array 168 208
RegExp 112 112
BitmapData 160 16480
IndexBuffer3D 40 40
VertexBuffer3D 40 40
Texture 424 424

Run the test app (debug player required)

getSize worked on these five classes:

  • XML
  • Object
  • Vector
  • Array
  • BitmapData

But it didn’t on these five classes:

  • String
  • RegExp
  • IndexBuffer3D
  • VertexBuffer3D
  • Texture

It’s not too surprising that GPU-side memory objects like IndexBuffer3D, VertexBuffer3D, and Texture didn’t report a size change, but it is quite surprising that such fundamental CPU-side memory objects like String and RegExp failed to show an increase in memory usage. After all, both of these classes have built-in language support such as "literal strings", automatic calling of toString(), and /regexp literals/.

Again, getSize is very useful in circumstances where it works. But be careful to check that the class you’re using it with is supported. The documentation does not warn you of this, so you’ll need to explicitly check every class you want to test.

Spot a bug? Have a question or suggestion? Post a comment!