/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ this.EXPORTED_SYMBOLS = ["Memory"]; const { classes: Cc, interfaces: Ci, utils: Cu } = Components; // How long we should wait for the Promise to resolve. const TIMEOUT_INTERVAL = 2000; Cu.import("resource://gre/modules/Services.jsm"); Cu.import("resource://gre/modules/Timer.jsm"); this.Memory = { /** * This function returns a Promise that resolves with an Object that * describes basic memory usage for each content process and the parent * process. * @returns Promise * @resolves JS Object * An Object in the following format: * { * "parent": { * uss: <int>, * rss: <int>, * }, * <pid>: { * uss: <int>, * rss: <int>, * }, * ... * } */ summary() { if (!this._pendingPromise) { this._pendingPromise = new Promise((resolve) => { this._pendingResolve = resolve; this._summaries = {}; Services.ppmm.broadcastAsyncMessage("Memory:GetSummary"); Services.ppmm.addMessageListener("Memory:Summary", this); this._pendingTimeout = setTimeout(() => { this.finish(); }, TIMEOUT_INTERVAL); }); } return this._pendingPromise; }, receiveMessage(msg) { if (msg.name != "Memory:Summary" || !this._pendingResolve) { return; } this._summaries[msg.data.pid] = msg.data.summary; // Now we check if we are done for all content processes. // Services.ppmm.childCount is a count of how many processes currently // exist that might respond to messages sent through the ppmm, including // the parent process. So we subtract the parent process with the "- 1", // and that’s how many content processes we’re waiting for. if (Object.keys(this._summaries).length >= Services.ppmm.childCount - 1) { this.finish(); } }, finish() { // Code to gather the USS and RSS values for the parent process. This // functions the same way as in process-content.js. let memMgr = Cc["@mozilla.org/memory-reporter-manager;1"] .getService(Ci.nsIMemoryReporterManager); let rss = memMgr.resident; let uss = memMgr.residentUnique; this._summaries["Parent"] = { uss, rss }; this._pendingResolve(this._summaries); this._pendingResolve = null; this._summaries = null; this._pendingPromise = null; clearTimeout(this._pendingTimeout); Services.ppmm.removeMessageListener("Memory:Summary", this); } };