I have a heap profile taken in Chrome Dev Tools, but I am not sure how to interpret the data. As a test, I created 10,000 WidgetBuilder objects, each with their own methods. I would like to profile out storing methods on instances versus the prototype and see how that affects memory and performance when my page loads.
Should I focus on Retained Size or Shallow Size?
Are the values listed in these columns in bytes?
What is considered a lot of memory?
You might want to start here:
https://developers.google.com/chrome-developer-tools/docs/heap-profiling
It goes into detail on how to understand what you're reading. As for what is considered a lot of memory that's a tricky question. If your website is targeted at mobile devices I would start there as a constraint. To come up with a good comparison I'd suggest running the profiler against sites that you use every day and observe the memory consumption there.
If you find you're using more memory than gmail you might want to rethink ;)
I also recommend checking out jspref:
http://jsperf.com/prototype-vs-instance-functions
There is a LOT of prior work done on that site in regards to performance testing. You might be able to save yourself some time.
I am about to ajaxify my website, but I have observed in some highly ajaxified websites like facebook itself that if you browse for quite some time without refreshing your browser gets slower, respectively more ram is being used and I suppose that is due to javascript "leftovers". It is kind of needless to ask this question if facebook's developers fail to accomplish this but hey, you only lose if you don't try. So the question is "is there a way I can clear variables and listeners from the previous page before loading the new one?". Thank you in advance!
That depends on the browser since each browser does its own Garbage Collection. You can however delete variables and HTML elements and if the GC thinks it can reclaim some memory, it will.
I suggest using some developer tools to actually watch the memory usage in real-time. In Chrome you can create a profile timeline and watch the memory usage grow/shrink. So you can actually see in real-time the effects your code have on memory management.
For testing I like to run cleanup code on a button click so I can know exactly when the code ran and how the memory usage was affected by the code.
And hey, since you're in there playing with dev. tools now, check-out the other tools available to you, they are amazingly helpful.
While debugging an application earlier, I noticed in Web Inspector that it appears a new session storage object (table?) was being created on every request.
Screenshot:
You'll notice under Resources -> Session Storage there are multiple entries for test.localhost.
So, I got distracted from what I was actually meant to be debugging and went on a search to find out what was causing this. I narrowed it down to when Modernizr.js is included on the page.
I've been using the Html5 Boilerplate in various different applications so I went back to the bare boilerplate code and am getting the same behaviour there as well.
Note, the screen shot above is from the standard boilerplate code, nothing else.
So, is this standard behaviour? Is it something I should be concerned about? I've certainly not noticed any performance issues, even after using my applications for a few hours at a time.
For reference, I'm running:
Safari (5.1.2)
Lion (10.7.2)
Latest boilerplate code (commit 9feb29f4654540297e358454b821b2e29b848be8)
This is a bug in the developer tools in Safari, it has been fixed in more recent WebKit nightly builds.
It's not strictly caused by the inclusion of Modernizr, but by it's use of window.sessionStorage to cache its results for future use.
Any time you reload a page that uses window.sessionStorage (Modernizr or not) another entry appears on the Session Storage list in the dev tools. Same behaviour is observed using window.localStorage and WebSQL databases.
I've lately been running into odd issues, which I'm starting to think are related to resource starvation in the browser.
In FF:
I'd been testing one of our web apps and suddenly things that should disappear after a couple seconds stopped disappearing. I tracked back to setTimeout just flat out refusing to work. After reloading the browser it was all clear, no issues.
In IE:
I regularly see issues where IE will refuse to do transparency all the sudden, simply reloading the page clears this up.
In both:
Though I can't say its related for sure, I see unexplainable behavior, things along the lines of variables not being available (undefined) when they should be.
Both browsers also show a steady increase in memory usage over time (memory leaks).
The javascript in the web app is heavy and it is a single load page (making those memory issues mentioned all the more painful). There are lots of in-efficiency, and various things that make one say "why would you do that?".
Has anyone encountered such things? Can you point out general resources that will help identify and resolve these issues?
You could try running your application against the Chrome Profiler http://code.google.com/chrome/devtools/docs/overview.html. You can profile the CPU and get snapshots of the browser heap, that should help locate any rogue stuff.
If your application is designed to work with the Internet Explorer: The Developer Toolbar also has a profiler.
Is there a way to find out how much memory is being used by a web page, or by my jquery application?
Here's my situation:
I'm building a data heavy webapp using a jquery frontend and a restful backend that serves data in JSON. The page is loaded once, and then everything happens via ajax.
The UI provides users with a way to create multiple tabs within the UI, and each tab can contain lots and lots of data. I'm considering limiting the number of tabs they can create, but was thinking it would be nice to only limit them once memory usage has gone above a certain threshold.
Based on the answers, I'd like to make some clarfications:
I'm looking for a runtime solution (not just developer tools), so that my application can determine actions based on memory usage in a user's browser.
Counting DOM elements or document size might be a good estimation, but it could be quite inaccurate since it wouldn't include event binding, data(), plugins, and other in-memory data structures.
2015 Update
Back in 2012 this wasn't possible, if you wanted to support all major browsers in-use. Unfortunately, right now this is still a Chrome only feature (a non-standard extension of window.performance).
window.performance.memory
Browser support: Chrome 6+
2012 Answer
Is there a way to find out how much memory is being used by a web page, or by my jquery application? I'm looking for a runtime solution (not just developer tools), so that my application can determine actions based on memory usage in a user's browser.
The simple but correct answer is no. Not all browsers expose such data to you. And I think you should drop the idea simply because the complexity and inaccuracy of a "handmade" solution may introduce more problem than it solves.
Counting DOM elements or document size might be a good estimation, but it could be quite inaccurate since it wouldn't include event binding, data(), plugins, and other in-memory data structures.
If you really want to stick with your idea you should separate fixed and dynamic content.
Fixed content is not dependant on user actions (memory used by script files, plugins, etc.)
Everything else is considered dynamic and should be your main focus when determining your limit.
But there is no easy way to summarize them. You could implement a tracking system that gathers all these information. All operations should call the appropriate tracking methods. e.g:
Wrap or overwrite jQuery.data method to inform the tracking system about your data allocations.
Wrap html manipulations so that adding or removing content is also tracked (innerHTML.length is the best estimate).
If you keep large in-memory objects they should also be monitored.
As for event binding you should use event delegation and then it could also be considered a somewhat fixed factor.
Another aspect that makes it hard to estimate your memory requirements correctly is that different browsers may allocate memory differently (for Javascript objects and DOM elements).
You can use the Navigation Timing API.
Navigation Timing is a JavaScript API for accurately measuring performance on the web. The API provides a simple way to get accurate and detailed timing statistics—natively—for page navigation and load events.
window.performance.memory gives access to JavaScript memory usage data.
Recommended reading
Measuring page load speed with Navigation Timing
This question is 5 years old, and both javascript and browsers have evolved incredibly in this time. Since this now possible (in at least some browsers), and this question is the first result when you Google "javascript show memory useage", I thought I'd offer a modern solution.
memory-stats.js: https://github.com/paulirish/memory-stats.js/tree/master
This script (which you can run at any time on any page) will display the current memory useage of the page:
var script=document.createElement('script');
script.src='https://rawgit.com/paulirish/memory-stats.js/master/bookmarklet.js';
document.head.appendChild(script);
I don't know of any way that you could actually find out how much memory is being used by the browser, but you might be able to use a heuristic based on the number of elements on the page. Uinsg jQuery, you could do $('*').length and it will give you the count of the number of DOM elements. Honestly, though, it's probably easier just to do some usability testing and come up with a fixed number of tabs to support.
Use the Chrome Heap Snapshot tool
There's also a Firebug tool called MemoryBug but seems it's not very mature yet.
If you want to just see for testing there is a way in Chrome via the developer page to track memory use, but not sure how to do it in javascript directly.
I would like to suggest an entirely different solution from the other answers, namely to observe the speed of your application and once it drops below defined levels either show tips to the user to close tabs, or disable new tabs from opening. A simple class which provides this kind of information is for example https://github.com/mrdoob/stats.js .
Aside of that, it might not be wise for such an intensive application to keep all tabs in memory in the first place. E.g. keeping only the user state (scroll) and loading all the data each time all but the last two tabs are opening might be a safer option.
Lastly, webkit developers have been discussing adding memory information to javascript, but they have gotten in a number of arguments about what and what should not be exposed. Either way, it's not unlikely that this kind of information will be available in a few years (although that information isn't too useful right now).
Perfect question timing with me starting on a similar project!
There is no accurate way of monitoring JS memory usage in-app since it would require higher level privileges. As mentioned in comments, checking the number of all elements etc. would be a waste of time since it ignores bound events etc.
This would be an architecture issue if memory leaks manifest or unused elements persist. Making sure that closed tabs' content is deleted completely without lingering event handlers etc. would be perfect; assuming that it's done you could just simulate heavy usage in a browser and extrapolate the results from memory monitoring (type about:memory in the address bar)
Protip: if you open the same page in IE, FF, Safari... and Chrome; and than navigate to about:memory in Chrome, it will report memory usage across all other browsers. Neat!
What you might want to do is have the server keep track of their bandwidth for that session (how many bytes of data have been sent to them). When they go over the limit, instead of sending data via ajax, the server should send an error code which javascript will use to tell the user they've used too much data.
You can get the document.documentElement.innerHTML and check its length. It would give you the number of bytes used by your web page.
This may not work in all browsers. So you can enclose all your body elements in a giant div and call innerhtml on that div. Something like <body><div id="giantDiv">...</div></body>