Skip to content

Instantly share code, notes, and snippets.

@past
Created August 28, 2013 11:05
Show Gist options
  • Save past/6364874 to your computer and use it in GitHub Desktop.
Save past/6364874 to your computer and use it in GitHub Desktop.
// -sp-context:browser
"use strict";
const Cc = Components.classes;
const Ci = Components.interfaces;
const Cu = Components.utils;
Cu.import("resource://gre/modules/devtools/Console.jsm");
let promise = Cu.import("resource://gre/modules/commonjs/sdk/core/promise.js").Promise;
let gMgr = Cc["@mozilla.org/memory-reporter-manager;1"]
.getService(Ci.nsIMemoryReporterManager);
let gChildMemoryListener = undefined;
let gTotal = 0;
// Returns a promise of the memory footprint of the tab with the specified
// URL and (optionally) outer window ID.
function getMemoryFootprint(url, outerId)
{
let deferred = promise.defer();
addChildObserversAndUpdate(() => {
deferred.resolve(processMemoryReporters(url, outerId));
});
return deferred.promise;
}
function addChildObserversAndUpdate(aUpdateFn)
{
let os = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
os.notifyObservers(null, "child-memory-reporter-request", null);
gChildMemoryListener = aUpdateFn;
os.addObserver(gChildMemoryListener, "child-memory-reporter-update", false);
gChildMemoryListener();
}
function processMemoryReporters(url, outerId)
{
let e = gMgr.enumerateMultiReporters();
while (e.hasMoreElements()) {
let mr = e.getNext().QueryInterface(Ci.nsIMemoryMultiReporter);
// |collectReports| never passes in a |presence| argument.
let handleReport = function(aProcess, aUnsafePath, aKind, aUnits, aAmount, aDescription) {
if (!aUnsafePath.contains("strings/notable/string") &&
flipBackslashes(aUnsafePath).contains(url) &&
(!outerId || aUnsafePath.contains(", id=" + outerId))) {
gTotal += aAmount;
}
}
mr.collectReports(handleReport, null);
}
return formatBytes(gTotal);
}
function flipBackslashes(aUnsafeStr)
{
// Save memory by only doing the replacement if it's necessary.
return (aUnsafeStr.indexOf('\\') === -1)
? aUnsafeStr
: aUnsafeStr.replace(/\\/g, '/');
}
function formatBytes(aBytes)
{
let unit = " MB";
let s;
let mbytes = (aBytes / (1024 * 1024)).toFixed(2);
let a = String(mbytes).split(".");
// If the argument to formatInt() is -0, it will print the negative sign.
s = formatInt(Number(a[0])) + "." + a[1] + unit;
return s;
}
function formatInt(aN, aExtra)
{
let neg = false;
if (hasNegativeSign(aN)) {
neg = true;
aN = -aN;
}
let s = [];
while (true) {
let k = aN % 1000;
aN = Math.floor(aN / 1000);
if (aN > 0) {
if (k < 10) {
s.unshift(",00", k);
} else if (k < 100) {
s.unshift(",0", k);
} else {
s.unshift(",", k);
}
} else {
s.unshift(k);
break;
}
}
if (neg) {
s.unshift("-");
}
if (aExtra) {
s.push(aExtra);
}
return s.join("");
}
function hasNegativeSign(aN)
{
if (aN === 0) { // this succeeds for 0 and -0
return 1 / aN === -Infinity; // this succeeds for -0
}
return aN < 0;
}
//////////////////////////////
// Demo:
let gURL = gBrowser.selectedBrowser.contentWindow.location.href;
console.log(">>> "+gURL);
getMemoryFootprint(gURL).then(console.log, console.error);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment