Performance Zone is brought to you in partnership with:

David Catuhe is a Microsoft HTML5 Evangelist based in Paris, France. He does much of his research on Windows 8, Kinect, and the various HTML5 standards and JS libraries. David is a DZone MVB and is not an employee of DZone and has posted 24 posts at DZone. You can read more from them at their website. View Full User Profile

Using Visual Studio’s Javascript Memory Analysis tool to find memory leaks on your Windows 8 Javascript app

04.25.2013
| 2915 views |
  • submit to reddit

Javascript is a wonderful language for developing Windows 8 apps. As a untyped, dynamic language, Javascript is really flexible but sometimes if you are not careful you may leave some memory leaks in your code.

But do not worry, Visual Studio includes a great tool called Javascript Memory Analysis in order to help you find out where the leaks are.

image

Using the Javascript Memory Analysis tool

This tool is available in the Debug menu of your Visual Studio:

image

Launching the tool will launch your app and will show this screen:

image

The first part of the window is dedicated to the real-time monitoring of the memory used by the application:

image

Right after you can find a button (Take Heap Snapshot) used to capture the instantaneous state of the memory heap (The control also indicates the size of the heap and the number of active objects):

image

By clicking on the heap size, a more detailed view is generated:

image

This view presents a sorted list of the objects by retained size, which means the objects consuming the most memory that are potentially easiest to free would be listed first.

For instance, in my app, I can see that the UrzaGatherer object retains almost 60 MB (which is normal because it handles a huge list of cards):

image

The view can also display:

  • a list of types sorted by occurrence count
  • a list of root objects (from the garbage collector point of view)
  • a list of DOM objects sorted by retained size
  • a list of WinRT objects sorted by retained size


All of these views can potentially help you find inconsistent memory usage.

Comparing snapshots

Each time you click on Take Heap Snapshot button, the system generates a new dump of the heap for further analysis. Furthermore, each snapshot indicates the difference of the heap size and objects count against previous snapshot.

This is the key for finding memory leaks.

For instance, in my app, I will take a first snapshot, navigate to a given page, then go back to home page and finally take a second snapshot. Doing this I will be able to see if the given page produces memory leaks.

image

We can see here that between the two snapshots, the heap size has grown of 6.12 MB and more than 53k objects were generated and still alive.  

By clicking on the heap size difference (+6.12 MB), you can view a detail of the heap size compared to previous snapshot:

image
The Dominators view indicates that new objects remain when we come back to the home page. You can use this view to identify unwanted objects.

In my case, the first line seems suspicious. By right-clicking on it, I can go to the Root view to see which function retains my objects:

image

We can see that the object is retained by a function called ImportFromTappedOut.

After looking for this function in my code, it turns out that this function is a global function which takes a  function as parameter:

ImportFromTappedOut = function (deckName, custom) {

The custom parameter is used by this function to call some specific user code. The main problem is that because the ImportFromTappedOut is a global function it will retain all the code referenced by the function affected to the custom parameter and in my case I used an anonymous function that references a lot of local DOM objects:

 Tools.ImportFromTappedOut("test", function () {
     var select = document.querySelector("#addToDeck");
     var count = document.querySelector("#addToDeckCount").value;

     listView.selection.getItems().then(function (items) {
         appBar.hide();
         appBar.sticky = false;
         listView.selection.clear();
…code continue…

And this exactly the problem described by the tool:

image

The solution is easy: I just have to call importFromTappedOut with a null function when I leave the page in order to allow the garbage collector to collect all retained objects (1.25 MB here).

I clearly encourage you to use this tool to detect and eradicate memory leaks. It is simple and really powerful and can help you get rid of memory problems.

More about the tool

Others articles you may find useful:



Published at DZone with permission of David Catuhe, author and DZone MVB. (source)

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)