Unity3D Unit Testing 2: Unity Test Tools

About RMC & Unity3D

Rivello Multimedia Consulting (RMC) provides consulting services for applications and games. RMC specializes in Unity3D development (see our work here). Please contact us today with any questions, comments, and project quotes.

As always, RivelloMultimediaConsulting.com/unity/ will be the central location for deep articles and tutorials, Facebook.com/RivelloMultimediaConsulting (like us!) will engage the growing RMC+Unity community, and for the latest opinions and cool links follow me at Twitter.com/srivello.

Intro To Unit Testing

To get the full background on what exactly are unit tests and more, checkout my “Unity3D Unit Testing 1” article first. It covers the basics as well as the historical challenges of testing within Unity. There I also cover the theory of TDD.

Unity Test Tools

In December, 2013 Unity Technologies released Unity Test Tools (UTT). While there had been several 3rd party options to attempting testing, now we have the official solution.

Figure 1. Unity Test Tools Released
Figure 1. Unity Test Tools Released

As Unity Technologies previously announced, they have been using testing internally on the core Unity3D codebase for a couple years. Lessons learned there helped to shape the free, newly released Asset Store Item Unity Test Tools.

The UTT package comes with 2 major areas of functionality. We cover them here.

1. Assertion Component

The assertion component is able to monitor the state of gameobjects while in playmode and pause the game if the condition is met. The primary use is debugging, where you can make the game stop in the exact frame the condition is met, thus enabling you to see the entire picture of when it occurs.

2. Integration Test

In order for you to test the integration between components, objects and assets, you need a higher level of tests and for this Unity has made the Integration Test Framework. Integration tests are also the easiest way of starting to write automation tests on a game in development, since they don’t have requirements on the architecture of the code.

This is obviously very powerful. Its early, but it is not yet clear to me how to utilize this in my project workflow. But I’ll figure it out soon. However, the following feature is perfect for me.

3. Unit Test

NUnit-Net-0

The lowest and most efficient level to do automation is at the unit level. Unity decided to use nUnit (nUnit.org) as the basis for the unit test framework, which is a well known framework for those already writing unit tests. In development, a ‘unit of work’ is a single logical functional use case in the system that can be invoked by some public interface (in most cases). A unit of work can span a single method, a whole class or multiple classes working together to achieve one single logical purpose that can be verified.

A unit test is an automated piece of code that invokes a unit of work in the system and then checks a single assumption about the behavior of that unit of work. Good unit testing is an art and a science and there is TONS of material online about it.

A good unit test is:

  •  Fully automated
  •  Consistently returns the same result
  •  Tests a single logical concept in the system

The Unity Test Tools

The free, newly released Asset Store Item Unity Test Tools, include the core testing libraries, examples of all 3 of the above types of tests, and documentation. If you find the documentation to be dry and obtuse (*hint*), then you are in luck. Checkout my video here. It cover only Unit Testing. The full source-code shown in the video is available for you too (See ‘Member Resources’ Below).

[tubepress video=”82440469″]

Member Resources

[private_Free member]Enjoy this members-only content!

[/private_Free member]

Unity3D Dev Diary: uEventDispatcher

About RMC & Unity3D

Rivello Multimedia Consulting (RMC) provides consulting services for applications and games. RMC specializes in Unity3D development (see our work here). Please contact us today with any questions, comments, and project quotes.

uEventDispatcher

Problem

Unity3D is a great gaming IDE and runtime. Like any tool I use regularly, I have many constructive criticisms as well. For example, there is no adequate one-to-many messaging system. The UnityEngine includes BroadcastMessage & SendMessage but it is not adequate and has many public, deserved criticisms.

Solution

Streamline messaging between classes using uEventDispatcher.

Benefits include;

  1. Easily add/remove and dispatch custom communication
  2. Strongly-typed data payload
  3. Compiler properly warns you about major misuse cases (mistyping, etc…)
  4. Works within any class type and requires no special ‘Interface’ or ‘Inheritance’
  5. Does not rely on reflection (slow performance) like BroadcastMessage/SendMessage

Usage

Here is an example that shows the COMPLETE API of uEventDispatcher.

[code]

//————————————–
// Imports
//————————————–
using UnityEngine;
using System.Collections;
using com.rmc.events;

//————————————–
// Class
//————————————–
public class TestEventDispatcher : MonoBehaviour
{

//————————————–
// Properties
//————————————–
// PRIVATE
private EventDispatcher eventDispatcher;

//————————————–
// Methods
//————————————–

// PUBLIC
/// <summary>
/// Start this instance.
/// </summary>
void Start ()
{

//CREATE
eventDispatcher = new EventDispatcher (this);

//ADD 0, 1, 2, OR MORE LISTENERS…
eventDispatcher.addEventListener (TestEvent.TEST_EVENT_NAME, _onCustomEvent1); //default is EventDispatcherAddMode.DEFAULT
eventDispatcher.addEventListener (TestEvent.TEST_EVENT_NAME, _onCustomEvent2, EventDispatcherAddMode.SINGLE_SHOT);

//TEST REMOVE
//eventDispatcher.removeAllEventListeners();
//eventDispatcher.removeEventListener (TestEvent.TEST_EVENT_NAME, _onCustomEvent1);

//TEST HAS
//Debug.Log (" hasEventListener(): " + eventDispatcher.hasEventListener (TestEvent.TEST_EVENT_NAME, _onCustomEvent1));

//TEST EVENT SETUP FROM 3 DIFFERENT SCOPES
eventDispatcher.dispatchEvent (new TestEvent (TestEvent.TEST_EVENT_NAME));

}

//————————————–
// Events
//————————————–
public void _onCustomEvent1 (IEvent iEvent)
{
Debug.Log (" 1. _onCustomEvent1(): " + iEvent);
}

public void _onCustomEvent2 (IEvent iEvent)
{
Debug.Log (" 2. _onCustomEvent2(): " + iEvent);
}

}

[/code]

Status

The project is now complete and live on the AssetStore. It is free. Check it out today!

Unity3D Unit Testing 1

About RMC & Unity3D

Rivello Multimedia Consulting (RMC) provides consulting services for applications and games. RMC specializes in Unity3D development (see our work here). Please contact us today with any questions, comments, and project quotes.

As always, RivelloMultimediaConsulting.com/unity/ will be the central location for deep articles and tutorials, Facebook.com/RivelloMultimediaConsulting (like us!) will engage the growing RMC+Unity community, and for the latest opinions and cool links follow me at Twitter.com/srivello.

Update: December 18, 2013, Unity Technologies releases the official “Unity Test Tools.” Read the full post below, then jump over to “Unity3D Unit Testing 2: Unity Test Tools“.

Intro To Unit Testing

As the author of the Art Of Unit Testing begins, “I used to feel that a ‘unit’ was the smallest possible part of a code base (a method, really). But in the past couple of years I’ve changed my mind”. Unit Testing is a fundamental of Extreme Programming too. Here’s how I define a unit test;

A unit test is an automated piece of code that invokes a unit of work in the system and then checks a single assumption about the behavior of that unit of work.

A unit of work is a single logical functional use case in the system that can be invoked by some public interface (in most cases). A unit of work can span a single method, a whole class or multiple classes working together to achieve one single logical purpose that can be verified.

A good unit test is:

  • Fully automated
  • Consistently returns the same result
  • Tests a single logical concept in the system

Reasons To Write Unit Tests

Development experts urge us all to test. Here are some top reasons;

  • Tests Reduce Bugs in New Features
  • Tests Reduce Bugs in Existing Features – With well-tested code, introducing new features rarely breaks existing functionality.
  • Tests Are Good Documentation – A concise code example is better than many paragraphs of documentation.
  • Tests Allow Refactoring \ Reduce the Cost of Change – Be more nimble. Experiment with confidence.
  • Testing Forces You to Slow Down and Think
  • Tests Reduce Fear – Having a complete test suite allows programmers to remove the fear of making changes or adding new features.

Unit Testing in Unity

So in Unity, we have three levels that need to be continuously tested:

  • C# code
  • Prefabs and single configured objects
  • Scene definitions for the final game – also known as levels.

There are some challenges to each, however the 3rd is probably the most tricky since much of its setup is done in visually through the editor (vs in C#). One tip is to configure all Game-Objects as prefabs, so that the scenes only contain a minimum of manual definitions. Some greater thought on the subject is outlined in this post.

The Unity Technologies team (creators of the Unity IDE) announced in 2013 Unity’s Runtime API Test Framework. While this is a great sign of the teams dedication to TDD (see next section) and to create tested, durable code for us to use, this framework is not available for us developers to use. The team released this chart showing how much of the Unity code-base is currently covered by testing (see Figure 1).

Figure 1. (Updated August, 2013)
Figure 1. (Updated August, 2013)

Test Driven Development (TDD)

TDD is the practice of creating your tests while you implement (rather than after). Moreover, TDD developers create the test first (returning the simplest incorrect value), runs it to see the failed test result, then implements the correct, complete implementation. The unit testing leads or ‘drives’ the programming workflow. This requires discipline but leads to a codebase with (good) heavy test coverage.

To perform a test you need 3 things; a testing framework to run the tests, you need the tests, and then you need something to test. Here is an example of a test and something being tested.

Example Test (Pseudocode)

//ASSUMING YOU HAVE A CUSTOM 'DoIntAddition' METHOD TO TEST...

[Test]
public void DoIntAdditionTest() {

//SETUP
int value1_int = 10;
int value2_int = 1;

//TEST
int result_int = DoIntAddition (value1_int, value2_int);

//EVALUATE VIA ‘ASSERTION’
Assert.IsTrue(result_int == (value1_int + value2_int) );
}

Example Test (Summary)

  1. Most Unit Testing Frameworks have some meta-tags (attributes) such as [test] that is used to indicate which methods are ‘test methods’
  2. You do any setup needed to cleanly prepare for your test (optional)
  3. You perform the test (such as calling a custom method to be tested as shown)
  4. You evaluate using an assertion. An assertion is your way as the tester to suggest the expected behavior. In this example it seems almost too simple, almost silly to test this method. However, once you create the test, you can be forever confident that the ‘DoIntAddition’ method will perform as expected, even if you later change the implementation of the method. This is the confidence you gain from Unit Testing.

Challenges In Unit Testing

General

Unit testing requires discipline from the team. Team leaders and project stakeholders must allow time not only to add the user-facing features, but also to create non-functional features such as under-the-hood unit tests for the codebase. Each team member too must be responsible for his or her own code. Writing tests for your own code (beforehand as in TDD per above) or during development is best.

First and foremost, a game is different to many other types of software in that a good portion of the code is handling input, and visuals/graphics/UI. These are two notoriously “un-unit-testable” parts of a system.

To help these issues, you can start by separating your visuals from your logic. This will make the logic more testable.

Specific Challenges for Unity3D

A staple of Unity development is the heavy use of the MonoBehaviour class. There is always logic in MonoBehaviours that you simply cannot take out and test in isolation. Now if you try to simply instantiate a MonoBehaviour in your script you will see this error in the console: You are trying to create a MonoBehaviour using the ‘new’ keyword. This is not allowed. MonoBehaviours can only be added using AddComponent(). Alternatively, your script can inherit from ScriptableObject or no base class at all. Each Unit3D testing frameworks has a solution to this issue. See the documentation for the framework you choose.

Another problem is the tight coupling of scripts to UnityEngine.dll*, which is not testable; if code depends on UnityEngine directly I can’t give it a mock implementation under my control, ergo it is not testable. This post covers more about the issue.

Links

Unity3D Unit Testing Articles

Unity3D Unit Testing Frameworks (Packages)

Unity3D Dev Diary: uMOM 1

About RMC & Unity3D

Rivello Multimedia Consulting (RMC) provides consulting services for applications and games. RMC specializes in Unity3D development (see our work here). Please contact us today with any questions, comments, and project quotes.

uMOM

Problem

Unity3D is a great gaming IDE and runtime. Like any tool I use regularly, I have many constructive criticisms as well. For example, there is no default Main.main() type ‘hook’ to centralize the entry into your runtime and no default way for UI and code to persist from scene to scene. I created a monolithic ‘SimpleManager’ class (see my HD training course video on architectures for more on that), however it is purposefully limited in scale. It is essentially a single manager packed with disparate responsibilities (sound, levels, object pooling, etc…). I knew there was a better solution.

Solution

Welcome to the Unity3D Manager of Managers (uMOM), pronounced as /you-mom/. I’m currently developing uMOM for the AssetStore.

The purpose of uMOM lean;

The uMOM package allows developers to add one or many reusable, custom manager classes to the project. Each ‘start’ automatically, have a predictable lifecycle (reset, add, update, remove), optionally receive ‘update()’ calls, optionally run during edit mode, and optionally persist between scenes. Managers operate as singletons and can easily address each other to collaborate.

Types of uMOM Managers

Really anything is possible, but here is the short list of use cases I will address first. Use some of mine or none of mine – then create your own. Most any existing mananger class you have can easily be converted for compatibility here. 

  • uEventManager -Streamline messaging between classes. Replace the need for Unity’s clunky ‘SendMessage’ and instead dispatch strongly typed objects. (The uEventManager will also be available separately).
  • Store references to audio clips (drag-n-drop) and control audio playback via C# from one place.
  • GUIManager – Layout UI which optionally persists between scenes. Centralize the controls to handle clicks, etc…
  • PoolManager – Optimize your run-time performance by persisting GameObject or prefab instances in RAM and displaying them as needed.
  • LevelManager – Queue up levels and perform transitions (e.g. fade-in-out) between them.
  • GameManager – While other managers are not project specific, this one likely is. Here you manage the core game mechanics, how the user wins and loses, store the score, etc…
  • SaveManager: Takes care of saving and loading user preferences and achievements.
  • MenuManager: Controls all menus, managing their animations, their contents, and their behaviors. Perhaps it heavily uses the GUIManager for layout.
  • Much, much, more…

The instructions of uMOM are concise;

  • 1. Select an existing uMOM manager class (from me, from the community) or create a new uMOM manager which subclasses BaseManager (which extends ScriptableObject). The class acts basically as an interface (because interfaces don’t serialize in Unity3D), allowing you maximum freedom in how you implement.
  • 2. Use the uMOM Unity Editor Window (See Figure 1) for all your needs. All compatible scripts in your project, regardless of folder location are shown here.
  • 3. Click ‘Convert’ (one time only) for the desired script. This efficiently creates a new ScriptableObject (e.g. MyManager.asset) for the original MonoScript (e.g. MyManager.cs)
  • 4. Click ‘Add’ (one time only) for the desired script. It is that step that actually puts your manager into use. Cool! You can click ‘Remove’ if you don’t want the manager to be in-use anymore.
  • 5. Edit your manager class source code however you like. No need to repeat the steps, your changes are hot-updated to the project. All this works in Edit Mode Or Play Mode.
Figure 1. (In Progress)
Figure 1. (In Progress)

 

Problems & BUGS!

During development I have hit many obstacles. All my issues continue to exist, even with the recent Unity 4.2.x release. Developing Unity Editor tools is a unique challenge compared to straight game development and it is unlike any other platforms I’ve used before. I’m sure all of these challenges can be solved.

I would LOVE some help resolving these issues. See this list (I’ll record a video soon if that would help you) and please comment below if you have confidence to solve any one area. I can share the code with you. I ask that any assistance be Work for Hire. Unfortunately on this particular project there is no partnership or co-ownership available. Once I have the project working, I plan to offer it as a premium package in the AssetStore.

1. Serialization

The uMOM class directly edits its public properties (as it should, right?). The many editor classes edit the SerializedObject and SerializedProperty of uMOM’s public properties (as it should right?). However in many places I see that I must STOP, change a value with a click in the uMOM Editor Window, then PLAY to have a change persist. Otherwise the change is lost next time I play/pause.

I have no workaround and I assume the issue is within my code. IDEAS?

2. Finding ‘All’ Assets

The uMOM Editor Window shows a list of all compatible MonoScripts (meaning all MonoScripts in Project window which extend BaseManager). That works. However, the programmatic listing of all compatible ScriptableObjects (meaning all ScriptableObjects in the Project window which have a type of a compatible MonoScript) is not so easy. Unity returns the ‘loaded’ (loose term) instances I want, but not ALL of them. The issue is well known (here, and here, and here, and more).

The common workaround I read online is to manually (with mouse) or programmatically (loop through all assets and call AssetDatabase.Load… [this crashes Unity IDE] or Selection.objects [This works inconsistently]… to ‘refresh’ the assets it can find). Manually = works but is not a long-term solution. Programmatically does not work.

Based on research I think this is a known Unity bug that Resources.FindObjectsOfTypeAll() and its deprecated equivalent Object.FindObjectsOfTypeAll, just do not really give you ‘all’. IDEAS?

Please Vote!

You can vote on this known bug (problem #2 above) here “Make FindObjectsOfTypeIncludingAssets find all just like the object picker” to encourage the Unity team to fix this issue. If you have nothing else to vote on, please cast your votes this way!

Using Symlinks For Unity Game Development

Unity 3D & C#

Unity3D is a powerful suite of tools (Project IDE, Code IDE, run-time) for game development.

As always, RivelloMultimediaConsulting.com/unity/ will be the central location for deep articles and tutorials, Facebook.com/RivelloMultimediaConsulting (like us!) will engage the growing RMC+Unity community, and for the latest opinions and cool links follow me at Twitter.com/srivello.

There is incredible momentum in the Unity3D product and its community. I recently posted “The Best C# Code Naming Conventions” and “Unity Best Practices”.  I came across one best-practice that requires a bit of setup, so here it is; using symlinks for game development.

Unity’s Weaknesses

The Unity Editor IDE does not facilitate collaboration between developers nor collaboration between projects.

  • 1.Want to use version control? Git? SVN? You can, but it is not easy. While certainly possible I suspect these strategies are purposefully kept difficult to encourage developers to purchase the Unity Collaboration & Unity Asset Server packaged features which are available for sale on the official Unity Asset Store.
  • 2. Want to share your code between projects (local or remote)? You can, and it is easy with custom packages (here is how), but it is not great. You are sharing a COPY of your code. Update your code and you have to re-export and re-import it everywhere. Difficult! I suspect its difficult for the same reason as above.

I’m happily surprised how great Unity Indie (free license) is. I really am. Yet, I’m still disappointed at these shortcomings.

Fortunately there are some free workarounds.

Workaround 1. Version Control

You can indeed use any version control to collaborate with other developers (local and remote). Its a bit tricky to setup (here is how, and here is some GIT advice). Enjoy!

Workaround 2. Symlinks

On Window (here1, here2), MacOSX (here), and Linux (here) you can create symlinks. In computing, a symbolic link (also symlink or soft link) is a special type of file that contains a reference to another file or directory. A symlink is SIMILAR to a shortcut (Windows) or alias (Mac). You click the symlink in Finder (Mac) or Windows Explorer (Windows) and it opens the original file. You’ve probably used them often. The added benefit of symlinks is that applications (most) cannot tell the difference between a symlink and the original file or folder. It is this difference we will exploit here.

Here are the instructions for using Symlinks with Unity on MacOSX to share code between three unity projects. The setup would be similar on Windows/Linux. Give it a try on your platform and post below with any suggestions!

Demo

Create Your Code Library

  1. Open the Unity Editor IDE
  2. File -> New Project… -> “/Users/srivello/Desktop/MyUnityLibrary”
  3. Assets -> Create -> Folder -> “MyUnityLibraryScripts”. This folder (and any subfolders) will be the location of 100% of the code you want to share. Let’s add one file to share.
  4. Assets -> Create -> C# Script -> “MyUnityLibraryScript” with the contents shown below.
  5. Drag “MyUnityLibraryScript” into “MyUnityLibraryScripts” within the Project window.
  6. File -> Save Project
  7. File -> Save Scene As… -> “MyUnityLibraryScene”

[actionscript3]<br />//SAMPLE CONTENTS FOR THE CLASS.<br />//ANY VALID CODE IS A GOOD TEST<br />public class MyUnityLibraryScript<br />{<br />//Test<br />public string sampleVariable = "Hello World";<br />}<br />[/actionscript3]

Create Your Game 1 Project

  1. Open the Unity Editor IDE
  2. File -> New Project… -> “/Users/srivello/Desktop/MyUnityGame1”
  3. Assets -> Create -> Folder -> “MyUnityLibraryScripts” with the contents shown below.
  4. File -> Save Project
  5. File -> Save Scene As… -> “MyUnityGame1”

Create Your Game 2 Project

  • Repeat the same steps for ‘MyUnityGame2’.

And now here are a few solutions to ‘share’ the code between the projects. Ideally A would work in all cases on all operating systems. I’m still working on that.

A. Create Symlink

UPDATE: A) The following fails on mac. Mac does not allow ‘hard links of folders’ which Unity wants. Mac can do soft links but the Unity Editor IDE does not recognize ‘soft links of folders’. Anyone have the following 3 lines working on PC? Share the lines as a comment below. Anyone have a workaround for MAC?

  1. Open the native MacOSX application ‘Terminal.app’
  2. Type “ln -s /Users/srivello/Desktop/MyUnityLibrary/Assets/MyUnityLibraryScripts/ /Users/srivello/Desktop/MyUnityGame1/Assets/MyUnityLibraryScripts” (without the quotes). This creates a symlink from the EXISTING folder in MyUnityLibrary to the NEW (symlink) folder in MyUnityGame1. Use absolute paths as I show here.
  3. Type “ln -s /Users/srivello/Desktop/MyUnityLibrary/Assets/MyUnityLibraryScripts/ /Users/srivello/Desktop/MyUnityGame2/Assets/MyUnityLibraryScripts” (without the quotes).

B. Use Rsync

  • You can download this free Mac App and it works great. (https://www.macupdate.com/app/mac/20983/arrsync) But you have to manually click ‘sync’ whenever you want to refresh the folder across your projects. Not bad. Anyone have a better workaround?

Summary

So what have we done here? Now both MyUnityGame1 project and MyUnityGame2 project have access to the code from MyUnityLibrary. Currently we have just one class in there. ANY of the 3 projects can be opened and you can edit/add new files. They all share a reference to the original MyUnityLibraryScripts folder. No need to COPY scripts! Great. No need to Export packages or Import packages! Great.

Gotchas!

The above workflow solves much of the confusion and problems reported by the community. However there are still some issues with my technique. Here are a few of the issues;

What Do YOU Think?

Have a comment? Please post below. This is a hot topic and I’ll respond promptly over the next month.

The Best C# Code Naming Conventions And Standards

In this post, I show the Microsoft coding conventions of C#. These are recommended by, but not required by, Unity Technologies for Unity’s C#. I compare those to my own RMC coding conventions (Rivello Multimedia Consulting).

It should be noted that the implementation of C# in Unity is based on Mono. Mono is a software platform designed to allow developers to easily create cross-platform applications. Sponsored by Xamarin, Mono is an open source implementation of Microsoft’s .NET Framework based on the ECMA standards for C# and the Common Language Runtime. As far as I can tell, Unity’s C# is the same as .NET’s C# in its approach to coding conventions.

Read the full, updated article at SamuelAsherRivello.com/coding-standards-csharp/

 

Unity 3D Best Practices

Unity 3D & C#

Unity3D is a powerful suite of tools (Project IDE, Code IDE, run-time) for game development.

As always, RivelloMultimediaConsulting.com/unity/ will be the central location for deep articles and tutorials, Facebook.com/RivelloMultimediaConsulting (like us!) will engage the growing RMC+Unity community, and for the latest opinions and cool links follow me at Twitter.com/srivello.

There is incredible momentum in the Unity3D product and its community.I recently posted “The Best C# Code Naming Conventions” and wanted to expand the discussion on best practices in this post below.

NOTE: I’m still working on this post, but wanted to get feedback on just the parts below. Drop a comment below.

Best Practices

Folder Organization

I created a custom menu option to create default folders.

unity_create_default_menu_v1

I add these folders to a new project (or existing) when it is first created. I put 3rd party packages into the ‘Community Assets’. The ‘Standard Assets’ folder is of course where Unity puts its own packages. I then rename the ‘[Project Name]’ folder to match my current project. Any suggestions?

unity_project_folders_v1

What Do YOU Think?

Have a comment? Please post below. This is a hot topic and I’ll respond promptly over the next month.

Unity3D & C# Training

There are MANY best practices included in my free, HD Video training series on “Unity3D & C#“. Check it out!

vimeo_screenflow_video_thumbnail_UWK_poster_v1

Fixing Memory Leaks with Adobe Flash Builder

On a recent project, we had a performance problem. The AIR project’s requirements include the heavy adding/removing of UI elements and over time we could easily see the performance slowed. We knew there was a something wrong. It was a memory leak. A memory leak starts when an object is stored in memory but cannot be accessed by the running code. When the undesired object cannot be freed from memory, and is not usable, it is a leak. Over time the application may leak (or re-leak the same issue) more and more. Eventually the application may show signs of the leak or even become unusable.

User Experience Symptoms Of  A Memory Leak

  • During regular use the application becomes more and more sluggish/slow. If there is nothing ‘new happening’ onscreen and no heavy ‘rendering’ it is more obvious to notice the Framerate-per-second (FPS) lower. You can use a small debug window (such as Hi-Res-Stats formerly MrDoobs Stats) to show the current FPS and estimated ram usage to help you notice this. If you see the FPS run at 30 for example during the first minute of use and 20 after 5 minutes, there may be a memory leak.
  • The application quits suddenly. This could be for many reasons, but it may be that the application runs out of memory.
  • Flash throws the memory-specific error ‘flash.errors.MemoryError’
Even if you see one of these symptoms it may not be obvious that there is a problem or that the problem is a memory issue. Or perhaps your development machine is high powered with ample RAM, yet your target user’s machines are slow. You don’t see the issue, but your users will. So how can we diagnose the issue. Luckily, the Flash Builder IDE has a ‘Profiler’. This program runs alongside your application and serves several key roles. You can monitor your applications USAGE of memory over time, and see a live list of all OBJECTS in memory (including references to those objects).

Profiling To Find Evidence Of A Memory Leak

  • Run your application with the Flash Builder Profiler. Run -> Profile As… -> etc…
  • Watch the ‘Memory Usage’ Panel
  • Look at the curves of Peak Memory (Red) and Current Memory (Blue). The analysis is totally application dependent. In your particular application, if you expect memory not to grow, but you see it grow, that is a problem. If you expect the memory to drop (UI removed from stage, arrays and vectors emptied, etc…) and you don’t see it drop, that is a problem. Herein lies the art of memory profiling. Consider to add a button to ‘Reset Application’, then click it and see that indeed the Current Memory drops to zero (0).
  • Watch the ‘Live Objects’ panel. Compare the 1. ‘Cumulative Instances’ and 2. ‘Instances’. For each object. #1 shows the total objects every created since the application started and #2 shows only those currently in memory. If these numbers are the same, and should not be, that is a problem. Perhaps you feel you have deleted a sprite from the stage or deleted another object from memory yet it still exists.


Tools And Tips For Finding And Fixing Memory Leaks (Must Read!)

If you want to play with a simple example you can download the example below (See ‘Member Resources’) below.

Example 1: Without Memory Leak

[actionscript3]
package
{
import flash.display.Sprite;
import flash.events.Event;

//USE A LOW FRAMERATE, SO WE CAN STUDY CLOSELY
[SWF(frameRate="1")]
public class MemoryLeakDemo extends Sprite
{

private var listOfDots_vector:Vector.<CustomDot>;
public function MemoryLeakDemo()
{
//REPEAT SOME CODE EVERY SECOND
addEventListener(Event.ENTER_FRAME, _onEnterFrame);

//CREATE A LIST
listOfDots_vector = new Vector.<CustomDot>();
}

protected function _onEnterFrame(event:Event):void
{
//EVERY FRAME WE…

//1. CREATE A NEW ‘DOT’ (A Red Circle Sprite)
//MEMORY NOTE: ‘var’ is a temporary variable.
//So CustomDot has 0 (permanent) references
var customDot : CustomDot = new CustomDot();

//2. ADD TO THE STAGE
//MEMORY NOTE: So CustomDot has 1 (permanent) reference; ‘this’
addChild(customDot);

//3. REMOVE TO THE STAGE
//MEMORY NOTE: So CustomDot has 0 reference
removeChild(customDot);

//So…
//THERE IS NO LEAK
//The GC will *mark* the ‘customDot’ as having 0 references and
//The GC will *sweep* it away from memory.

}

}
}
[/actionscript3]

Example 2: With Memory Leak

[actionscript3]
package
{
import flash.display.Sprite;
import flash.events.Event;

//USE A LOW FRAMERATE, SO WE CAN STUDY CLOSELY
[SWF(frameRate="1")]
public class MemoryLeakDemo extends Sprite
{

private var listOfDots_vector:Vector.<CustomDot>;
public function MemoryLeakDemo()
{
//REPEAT SOME CODE EVERY SECOND
addEventListener(Event.ENTER_FRAME, _onEnterFrame);

//CREATE A LIST
listOfDots_vector = new Vector.<CustomDot>();
}

protected function _onEnterFrame(event:Event):void
{
//EVERY FRAME WE…

//1. CREATE A NEW ‘DOT’ (A Red Circle Sprite)
//MEMORY NOTE: ‘var’ is a temporary variable.
// So CustomDot has 0 (permanent) references
var customDot : CustomDot = new CustomDot();

//2. ADD TO THE STAGE
//MEMORY NOTE: So CustomDot has 1 (permanent) reference; ‘this’
addChild(customDot);

//2B. CREATE ANOTHER REFERENCE TO THE DOT
listOfDots_vector.push(customDot);

//3. REMOVE TO THE STAGE
//MEMORY NOTE: So CustomDot has 0 reference
removeChild(customDot);

//So…
//THERE *IS* A LEAK
//While we are correctly calling removeChild
//There is a reference left in ‘2B’ above.

}

}
}
[/actionscript3]

Next Steps

  • Download the code and check it out! (See Member Resources)
  • Comment below with your thoughts.
  • NOTE: Flash Builder 4.7 (BETA2) has new Profiler called “Monocle“. It looks very exciting, yet this article focuses on the currently available (non-BETA) profiler.

Member Resources

[private_Free member]Enjoy this members-only content!

[/private_Free member]