Created
August 28, 2013 11:05
-
-
Save past/6364874 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// -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