mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-26 19:55:39 +00:00
5bc9e5bb2b
This adds a mechanism that discards tabs when the browser detects a low-memory scenario. Tabs are discarded in LRU order prioritizing regular tabs over pinned ones, pinned ones over tabs playing audio and all of the previous over pinned tabs playing audio. Differential Revision: https://phabricator.services.mozilla.com/D20476 --HG-- extra : moz-landing-system : lando
77 lines
2.1 KiB
JavaScript
77 lines
2.1 KiB
JavaScript
/* -*- mode: js; indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
|
/* 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/. */
|
|
|
|
"use strict";
|
|
|
|
var EXPORTED_SYMBOLS = ["TabUnloader"];
|
|
|
|
const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
|
|
|
/**
|
|
* This module is responsible for detecting low-memory scenarios and unloading
|
|
* tabs in response to them.
|
|
*/
|
|
|
|
var TabUnloader = {
|
|
/**
|
|
* Initialize low-memory detection and tab auto-unloading.
|
|
*/
|
|
init() {
|
|
if (Services.prefs.getBoolPref("browser.tabs.unloadOnLowMemory", true)) {
|
|
Services.obs.addObserver(this, "memory-pressure", /* ownsWeak */ true);
|
|
}
|
|
},
|
|
|
|
observe(subject, topic, data) {
|
|
if (topic == "memory-pressure" && data != "heap-minimize") {
|
|
unloadLeastRecentlyUsedTab();
|
|
}
|
|
},
|
|
|
|
QueryInterface: ChromeUtils.generateQI([
|
|
Ci.nsIObserver,
|
|
Ci.nsISupportsWeakReference,
|
|
]),
|
|
};
|
|
|
|
function unloadLeastRecentlyUsedTab() {
|
|
let bgTabBrowsers = getSortedBackgroundTabBrowsers();
|
|
|
|
for (let tb of bgTabBrowsers) {
|
|
if (tb.browser.discardBrowser(tb.tab)) {
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Sort tabs in the order we use for unloading, first non-pinned, non-audible
|
|
* tabs in LRU order, then non-audible tabs in LRU order, then non-pinned
|
|
* audible tabs in LRU order and finally pinned, audible tabs in LRU order. */
|
|
function sortTabs(a, b) {
|
|
if (a.tab.soundPlaying != b.tab.soundPlaying) {
|
|
return a.tab.soundPlaying - b.tab.soundPlaying;
|
|
}
|
|
|
|
if (a.tab.pinned != b.tab.pinned) {
|
|
return a.tab.pinned - b.tab.pinned;
|
|
}
|
|
|
|
return a.tab.lastAccessed - b.tab.lastAccessed;
|
|
}
|
|
|
|
function getSortedBackgroundTabBrowsers() {
|
|
let bgTabBrowsers = [];
|
|
|
|
for (let win of Services.wm.getEnumerator("navigator:browser")) {
|
|
for (let tab of win.gBrowser.tabs) {
|
|
if (!tab.selected && tab.linkedBrowser.isConnected) {
|
|
bgTabBrowsers.push({ tab, browser: win.gBrowser });
|
|
}
|
|
}
|
|
}
|
|
|
|
return bgTabBrowsers.sort(sortTabs);
|
|
}
|