Intro To Profiling Applications

From FDT Documentation

Jump to: navigation, search
Profiler.png

Profiling is an important part of software development. The FDT Profiler helps developers detect performance issues within a Flash application. If you're creating a simple image carousel, a profiler is something that you may not need. If you're building an AIR application that will work on a computer kiosk, running for hours on end, a profiler will likely be a life saver.

There two different approaches to profiling, Memory Profiling and Performance Profiling. We'll go over these two separate modes in future walkthroughs. For now, we're going to focus on becoming familier with launching the profiler, exploring the Profiling Perspective, and have a small introduction to Memory Profiling.


Contents

Source Files

Download soruce files.png

Video

Getting Started

Visit the Downloads page to download the source code used in the Basic AS3 Tutorial to get started. Or create a new project and copy and paste the source code below.

Main.as:

package demo {
	import graphics.shapes.Circle;
 
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
 
	public class Main extends Sprite {
		private var circles : Array = [];
 
		public function Main() {
			this.stage.addEventListener(MouseEvent.MOUSE_DOWN, start_circles);
			this.stage.addEventListener(MouseEvent.MOUSE_UP, stop_circles);
		} 
 
		private function start_circles(event : MouseEvent) : void {
			this.addEventListener(Event.ENTER_FRAME, draw_circles);
		}
 
		private function stop_circles(event : MouseEvent) : void {
			this.removeEventListener(Event.ENTER_FRAME, draw_circles);
 
			while(circles[0]) {
				this.removeChild(circles.pop());
			}
		}
 
		private function draw_circles(event : Event) : void {
			// with no referece this won't be garbage collected
			addChild(create_circle());
			// hold a referce in array so it can be removed from stage 
                       //and garbage collected
			circles.unshift(create_circle());
			addChild(circles[0]);
		}
 
		private function create_circle() : Circle {
			var circle : Circle = new Circle();
			circle.x = this.stage.stageWidth * Math.random();
			circle.y = this.stage.stageHeight * Math.random();
			return  circle;
		}
	}
}


Cirlce.as:

package graphics.shapes {
	import flash.display.Shape;
 
	public class Circle extends Shape {
		public function Circle() {
			this.graphics.beginFill(0xffffff * Math.random());
			this.graphics.drawCircle(0, 0, 20 * Math.random());
		}
	}
}

How The Example Project Works

With our project setup and our Main.as Img preview.png class and Circle.as class Img preview.png setup. We'll quickly cover the code. Circle is just a class that draws a circle of random size and color. It's also located in the graphics.shapes namespace (package). Main is a class that creates circles and adds them to the stage. The only bit of code to note is this:

private function draw_circles(event : Event) : void {
	// with no referece this won't be garbage collected
	addChild(create_circle());
	// hold a referce in array so it can be removed from stage and garbage collected
	circles.unshift(create_circle());
	addChild(circles[0]);
}


Here we're creating two circles - one is placed directly on the stage and the other is having a reference (pointer) stored into an Array so we can retrieve it later:

private function stop_circles(event : MouseEvent) : void {
	this.removeEventListener(Event.ENTER_FRAME, draw_circles);
 
	while(circles[0]) {
		this.removeChild(circles.pop());
	}
}


On MOUSE_UP, we're stopping the creation of new circles and each Circle in the circles array is being taken out of the array and then removed from the stage. This will remove any references to the circle we've created so it can be easily deleted from memory (garbage collected).

Running The SWF

Before profiling, lets just run the .SWF to see what's going on. This demo already has a launch configuration included Img preview.png, and to access this we'll jump to the Run Configurations window Img preview.png, select it Img preview.png and hit Run Img preview.png. When the window pops up Img preview.png, press down on the stage (MouseEvent.MOUSE_DOWN) to begin drawing circles Img preview.png and then release the mouse (MouseEvent.MOUSE_UP) to have half of them disappear Img preview.png.

The circles that disappeared will be eligible for garbage collection and the ones on the stage will not.

Launching The Profiler

Now, let's get to the profiler. Again, we have multiple ways of launching the profiler, but to make sure we're using the same launch profile, let's go to the profile menu and choose our 'ProfileTest' launch. FDT will compile and and launch the .SWF then switch to the Profile perspective Img preview.png. For now let's move off the External SWF Viewer and focus on the Profiler Perspective Img preview.png.

note: In this example, the views have been moved around to make best use of the space available. You can set it up however you like.

note: By default a .SWFs background will become transparent when loaded onto another .SWF. The profiler is actually loading your .SWF into another .SWF. That is why the background in this example appears with the default Flex background color. The background color you are seeing is the background color of the Profiler .SWF. If you are using the Flex Framework you will see the profiler .SWF launch and then your Flex App load on top of it- and your 'background' color would then be the color as defined by the Flex Application.

The Profiler Perspective

Memory Graph

The top part is the Memory Graph Img preview.png. This is a visual representation of the .SWF's memory footprint displayed over time. This is where you'll be looking to compare Peak Memory (a total of all Objects created) and Current Memory (Objects that are currently active in memory).

Live Objects

The next view is the LiveObjects view Img preview.png. This provides a breakdown of the objects created and how much memory that type of object takes up. In this example we can see that the String type takes up .31 percent of memory in our app.

Profile Monitor

The Profile Monitor is where we control the profile process Img preview.png. Use this when you want to force garbage collection Img preview.png, terminate Img preview.png or suspend (pause) the profiler Img preview.png. When using these controls, make sure you have the currently running process selected, otherwise you won't be able to control the active profiling session Img preview.png.

Console

The Console view here is the same as it exists elsewhere in FDT Img preview.png. It simply provides an output of FDT's actions.

Profiler In Action

Bring focus back to the running .SWF and press and hold the mouse button. As you do this, circles will begin appearing on the stage. You'll see the Memory Graph begin to climb and the Live2Objects view being updated Img preview.png. When the mouse is released, half of the circles will disappear. The objects that disappeared are now eligible for garbage collection. For the standard player release, Flash's garbage collection is designed to be automated and not to be user initiated. Since we are using the debug player, FDT has access to an API that allows developers to initiate garbage collection as they wish. To initiate garbage collection, press the Run Garbage Collection button Img preview.png.

Instantly, you'll see a dip in the Current Memory within the Memory Graph view and the Instances column within the LiveObjects view will drop Img preview.png. This drop represents the deletion of those circles we removed from the stage.

Filters

To get a better idea of what is going on, let's pause the execution of the .SWF and profiler by pressing the Suspend button Img preview.png. With everything paused, let's take a closer look at the filters that are available. Here we have two important filters: Filter internal packages Img preview.png and Filter native objects Img preview.png. To a get a better idea of what garbage collection did for us, click on the Filter native objects filter. Here we can see the objects we created, Main and Circle Img preview.png. Notice that there are 305 circles active compared to 611 that have been generated in total. Our ENTER_FRAME event handler was creating two objects total - one we explicitly generate a reference for and one that we anonymously add. Our MOUSE_UP handler is then removing the circles we created a reference for and leaving the others behind. That is why when the garbage collector executed it removed exactly half of the circles, 305, of the total 610.

Memory Snapshots

Sometimes it doesn't make sense to pause your .SWF to inspect it. That is what Memory Snapshots are for. If your .SWF is not already executing, resume it now. After minimizing the Console view, prepare to take a snapshot by selecting the running process and press the Create Memory Snapshot button Img preview.png.

note: this example was restarted to clean up the UI a bit so it's not going to match exactly previous screens;however, the steps to this point are the same.

FDT will then create a memory snapshot of the running .SWF Img preview.png. Let's wait a little bit and then hit the garbage collection button and wait for the memory to be cleared Img preview.png. After the memory has been cleared take another snapshot Img preview.png.

With both snapshots created, we can now take a closer look at what was going on at that moment and even compare the two. Initiate the Memory Snapshot view by double clicking on one of the snapshots Img preview.png. To clear things up a bit, let's use the Filter native objects filter on the snapshot Img preview.png. This snapshot now provides a detailed report of the status of the application at a specific time. We can dive even deeper and investigate the instances associated with that type by expanding the Class type Img preview.png. Clicking an a particular instance Img preview.png will then activate the Back References Img preview.png associated with it. The Allocation Trace is also available to us and provides further information about the running .SWF Img preview.png.

Another useful features regarding Snapshots is the ability to compare Snapshots. Do this by selecting the two available Snapshots and pressing the Compare Snapshot button Img preview.png. A new Compared Snapshot will be created Img preview.png. Double click on this and the Compare Snapshot view will open Img preview.png. Here Missing Objects and Additional Objects can be investigated. In our case, the Missing Objects are those that were deleted when we initiated garbage collection and the Additional Objects are the various events being dispatched by the mouse events and ENTER_FRAME event.

FAQ

Q: Why doesn't FDT either switch perspectives or ask me to switch perspectives?

A: Check out the FAQ:
FAQ#When I Debug or Profile My Application, The Perspective Doesn't Change

Q: What are the key benefits of the FDT Profiler?

A: Here some:

  • launch configuration makes it possible to setup different scenarios and start them with just one click
  • reuse existing launch configurations, if existing configurations are reused for profiling you don't have to configure customized compiler arguments again.
  • filters can be set via launcher
  • predefined filters for internal packages, native objects + internal actions
  • custom filters for included packages (positive) + excluded packages (negative)
  • buttons for enabling/disabling all predefined + custom filters during profiling -> fast comparison
  • bars for percentage values to get a visual impression of all ratios
  • allocation trace + back references in one view within (compared) memory snapshot
  • profiling with system browser, external SWF viewer + AIR Debug launcher (Standalone player does not support profiling)
  • detailled data collection, e.q. ByteArray
  • filtered startup data for performance snapshots can be resetted at any time to get a full data performance snapshot, it really works like a filter
  • filtering startup data for performance profiling can be triggered automatically (customizable duration)
  • debugger can be used simultaneously

Wrap Up

There's still plenty more to cover when it comes to profiling. Keep an eye out for more profiling tutorials coming soon.

Get FDT5