Intro To Profiling Applications

From FDT Documentation

(Difference between revisions)
Jump to: navigation, search
(Console)
(Profiler In Action)
Line 121: Line 121:
=Profiler In Action=
=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 '''LiveObjects''' view being updating [021]. When the mouse is released, half of the circles will disappear. These 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 [022].
+
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 '''LiveObjects''' view being updating [[File:08_021.gif|10px]]. When the mouse is released, half of the circles will disappear. These 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 [[File:08_022.gif|10px]].
-
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 [023].  This drop represents the deletion of those circles we removed from the stage.  
+
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 [[File:08_023.gif|10px]].  This drop represents the deletion of those circles we removed from the stage.  
==Filters==
==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 [024]. With everything paused, lets take a closer look at the filters that are available. Here we have two important filters: '''Filter internal packages''' [025] and '''Filter native objects''' [026]. 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''' [027]. 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'''.
+
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 [[File:08_024.gif|10px]]. With everything paused, lets take a closer look at the filters that are available. Here we have two important filters: '''Filter internal packages''' [[File:08_025.gif|10px]] and '''Filter native objects''' [[File:08_026.gif|10px]]. 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''' [[File:08_027.gif|10px]]. 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==
==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 [029].
+
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 [[File:08_028.gif|10px]] .
''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.''
''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. Let's wait a little bit and then hit the garbage collection button and wait for the memory to be cleared [031]. After the memory has been cleared take another snapshot [032].
+
FDT will then create a memory snapshot of the running .SWF [[File:08_029.gif|10px]]. Let's wait a little bit and then hit the garbage collection button and wait for the memory to be cleared [[File:08_031.gif|10px]]. After the memory has been cleared take another snapshot [[File:08_032.gif|10px]].
-
With both snapshots created [033], 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 [034]. To clear things up a bit, let's use the '''Filter native objects''' filter on the snapshot [035].  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 [036]. Clicking an a particular instance [07] will then activate the '''Back References''' [038] associated with it. The '''Allocation Trace''' is also available to us and provides further information about the running .SWF [039].
+
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 [[File:08_033.gif|10px]]. To clear things up a bit, let's use the '''Filter native objects''' filter on the snapshot [[File:08_034.gif|10px]].  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 [[File:08_035.gif|10px]]. Clicking an a particular instance [[File:08_036.gif|10px]] will then activate the '''Back References''' [[File:08_037.gif|10px]] associated with it. The '''Allocation Trace''' is also available to us and provides further information about the running .SWF [[File:08_038.gif|10px]].
-
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 [040]. A new '''Compared Snapshot''' will be created [041]. Double click on this and the [[Compare Snapshot]] view will open [042]. 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.
+
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 [[File:08_040.gif|10px]]. A new '''Compared Snapshot''' will be created [[File:08_041.gif|10px]]. Double click on this and the [[Compare Snapshot]] view will open [[File:08_042.gif|10px]]. 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.

Revision as of 21:16, 22 September 2010

Profiling is an important part of software development. 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 is going to be almost necessary and likely a life saver.

Contents

Getting Started

Import this project into FDT ( learn about importing and exporting via Creating Project Templates) or copy and paste the code below to follow along:

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 08 001.gif class and Circle.as class 08 002.gif setup. We'll quickly cover the code. Cirlce 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 08 003.gif, and to access this we'll jump to the Run Configurations window 08 004.gif, select it 08 005.gif and hit Run 08 006.gif. When the window pops up 08 007.gif, press down on the stage (MouseEvent.MOUSE_DOWN) to begin drawing circles 08 008.gif and then release the mouse (MouseEvent.MOUSE_UP) to have half of them disappear 08 009.gif.

Those 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 go to the profile menu and choose our 'ProfileTest' launch [010]. FDT will compile and and launch the .SWF then switch to the Profile perspective 08 011.gif. For now let's move off the External SWF Viewer and focus on the Profiler Perspective 08 012.gif.

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.

The Profiler Perspective

Memory Graph

The top part is the Memory Graph 08 013.gif. 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 08 014.gif. 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 08 015.gif. Use this when you want to force garbage collection 08 016.gif, terminate 08 017.gif or suspend (pause) the profiler 08 018.gif. 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 08 019.gif.

Console

The Console view here is the same as it exists elsewhere in FDT 08 020.gif. 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 LiveObjects view being updating 08 021.gif. When the mouse is released, half of the circles will disappear. These 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 08 022.gif.

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 08 023.gif. 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 08 024.gif. With everything paused, lets take a closer look at the filters that are available. Here we have two important filters: Filter internal packages 08 025.gif and Filter native objects 08 026.gif. 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 08 027.gif. 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 08 028.gif .

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 08 029.gif. Let's wait a little bit and then hit the garbage collection button and wait for the memory to be cleared 08 031.gif. After the memory has been cleared take another snapshot 08 032.gif.

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 08 033.gif. To clear things up a bit, let's use the Filter native objects filter on the snapshot 08 034.gif. 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 08 035.gif. Clicking an a particular instance 08 036.gif will then activate the Back References 08 037.gif associated with it. The Allocation Trace is also available to us and provides further information about the running .SWF 08 038.gif.

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 08 040.gif. A new Compared Snapshot will be created 08 041.gif. Double click on this and the Compare Snapshot view will open 08 042.gif. 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.

Get FDT5