Memorybug

From FirebugWiki

(Difference between revisions)
Jump to: navigation, search
(Future UI)
Line 115: Line 115:
== Future UI ==
== Future UI ==
-
There are surely better ways how to integrate the memory-profiling feature with the rest of Firebug UI and how to present all information to the user. These are only limited by available APIs.  
+
There are surely better ways how to integrate the memory-profiling feature with the rest of Firebug UI (i.e. the other panels) and also how to present all gathered information to the user. These are only limited by the power of available APIs.  
Following list summarizes some ideas:
Following list summarizes some ideas:
-
* There could be a new <code>console.memoryProfile()</code> method that allows to automate profiling by the page itself. The result summary info can be logged directly into the '''Console''' panel similarly to what ''console.profileStart'' and ''console.profileEnd'' methods do.
+
* There should be a new <code>console.memoryProfile()</code> method that allows to automated profiling. The result info can be logged directly into the '''Console''' panel similarly to what ''console.profileStart'' and ''console.profileEnd'' methods do.
-
* The '''Dom''' panel could displays number of raw bytes consumed by an object for every entry. Such number would be available as soon as the profiler has been launched.
+
* The '''Dom''' panel should displays number of raw bytes consumed for every displayed object (such number would be available as soon as the profiler has been launched).
-
* The '''Memory''' panel could also support a ''Persist'' feature and archive memory-snapshots made at different time within the page life time (both manually or automatically using the console object). In such a case the history should allow to see how the memory consumption increased/decreased.
+
* The '''Memory''' panel should also support a ''Persist'' feature (like '''Net''' and '''Console''' panels) and archive memory-snapshots made at different times within the page life cycle (both manual or automatic profiling should be respected). In such a case the history should allow to see how the memory consumption increased/decreased.
 +
* Every JS object appearing in memory-profiling results should be linked with the '''Script''' panel showing it's location in the source and also linked with the '''DOM''' panel showing the location in DOM hierarchy.
 +
 +
* Finally, similarly to the '''Net''' panel, it should be possible to export all the info into a file.
=Resources=
=Resources=

Revision as of 18:41, 26 March 2010

Contents

Motivation

One of the most requested features (I think the one just after saving CSS changes) is a support for analyzing memory that is consumed by a web page.


Goals

A memory profiler UI should be smoothly integrated with Firebug UI (preferably linking and reusing existing UI elements) and providing such visual information that helps the user to answer/examine following questions.


  • What is the state of the memory consumed by the current page just now (a snapshot)?
  • How can I see a list of all JS objects created by the page?
  • What are the relations among created objects (prototype, constructor, parent, references, referents)?
  • How much memory is consumed by this object?
  • Where this object was crated in the source code (url, line number)?
  • How to automatically execute memory profiler and analyze gathered data over page-life time?
  • I know there are memory leaks, how can I find them?
  • Are there any objects ready for garbage collecting at this moment?


Memory Profiler APIs

Available memory-profiler APIs allow to examine all JS objects in Firefox runtime (JSRuntime). The current implementation freezes it and creates a new memory profiling runtime, which is consequently used to access the Firefox runtime. There is also a way how to provide custom Javascript code that is executed within memory profiling runtime and collecting required info (see more).

Every object in a runtime is refereed by a unique ID so, the first thing to do is getting a list of all existing JS objects (getObjectTable). Another function (getObjectInfo allows to get a JSON able data structure for every object according to specifie ID.

The structure can contain following fields (depends on the actual JS object).

  • id
  • nativeClass - e.g. Function, Object, etc.
  • size - The total storage requirements for the object, including the (shared) memory used for property descriptors (JS_GetObjectTotalSize()).
  • parent (id)
  • prototype (id)
  • functionSize - Size of the function object plus size of the script (JS_GetFunctionTotalSize()).
  • scriptSize - Memory used to store the bytecode corresponding to the script, including things like atoms i.e. constant strings in the code (JS_GetScriptTotalSize()).
  • name - Name of a function (not available for instances)
  • filename - URL of the file where a function is defined (not available for instances).
  • lineStart - Line Number where a function object definitions begins (not available for instances).
  • lineEnd - Line Number where a function object definitions ends (not available for instances).
  • children - List of referred objects.


Missing APIs

  • Even if there are fields (size, functionSize, scripSize) that indicates some size info, the actual number of bytes used by an object is missing. This is probably the most critical as Firebug users would probably like to see this information.
  • Name field is not available for simple JS objects (like e.g. var o = {a:1, b:2}). These can be only refered by list of existing properties. This makes the mental association with the actual JS object in the code hard (there is no even filename and line info).
  • It would be also useful if JS Objects has another field constructor, which would help to link it to the function that was used for instantiation.


Memorybug

There is a working Firebug extension called Memorybug that shows what kind of information is possible to get from the currently available memory-profiling APIs. So, far this extension is in real alpha phase.


Here is the recommended configuration to run Memorybug.

As soon as you have all setup, load a test page and follow instructions on it.


Current UI

Memorybug plug itself into the Firebug UI as a new Memory panel.

Memory-panel.png

After clicking the Memory Snapshot button, Jetpack's profileMemory function is used to get all JS objects from the Firefox runtime. The list of objects is filtered and so, only those that belongs to the current page (window) or an embedded iframe (window) are further analyzed.

Memory-functions.png

This screen-shot shows several groups displayed as the result of profiling. The Functions group shows all JS Functions object found on the page and in an embedded iframes. The function name is clickable and navigates the the user into the Script panel.


One problem is that dynamically injected code breaks line numbers. See the next screenshot, that shows what happens if the Firebug Console panel is enabled.

Memory-injected-functions.png

All functions defined on the well known console object are also visible. However these are injected dynamically by Firebug, which breaks lineStart and lineEnd data.


Another screenshot shows list of JS objects found on the page and number of their instances.

Memory-injected-functions.png


Since there are no real classes in Javascript (like e.g. in C++ or Java) there is currently no way how to identify an instance, except of listing its properties and defining something called a shape.

Memory-instances.png

Firebug users/developers can easily recognize the injected console object (2 instances, since there is an iframe) and also an object with name, age, desc properties (2 instances). The later corresponds to the following script on the page.

<script type="text/javascript">
function Person(name, age, desc) {
    this.name = name;
    this.age = age;
    this.desc = desc;
}

var p2 = new Person("Jack", 35, "Good guy");
var p3 = new Person("Peter", 27, "Bad guy");
</script>


The last screenshot shows list of windows/iframes (URLs) with additional info for each window.

Memory-windows.png

This is another approach used by [3]. Showing list of objects that are crated within specific URL also grouped by a line at which they were created. In this case 1 function object was created at line: 11 in innerFrame.html. The source code at this line is function _TestFromIframe()


Future UI

There are surely better ways how to integrate the memory-profiling feature with the rest of Firebug UI (i.e. the other panels) and also how to present all gathered information to the user. These are only limited by the power of available APIs.

Following list summarizes some ideas:

  • There should be a new console.memoryProfile() method that allows to automated profiling. The result info can be logged directly into the Console panel similarly to what console.profileStart and console.profileEnd methods do.
  • The Dom panel should displays number of raw bytes consumed for every displayed object (such number would be available as soon as the profiler has been launched).
  • The Memory panel should also support a Persist feature (like Net and Console panels) and archive memory-snapshots made at different times within the page life cycle (both manual or automatic profiling should be respected). In such a case the history should allow to see how the memory consumption increased/decreased.
  • Every JS object appearing in memory-profiling results should be linked with the Script panel showing it's location in the source and also linked with the DOM panel showing the location in DOM hierarchy.
  • Finally, similarly to the Net panel, it should be possible to export all the info into a file.

Resources

  1. Web Application Memory Profiling, Take Two
  2. Memory Profiler 0.0.5 AMO
  3. Another Memory Profiler, Techno Barje
  4. Fun with SpiderMonkey
  5. Jetpack Binary Components
  6. Memorybug 0.1 Source
Personal tools