Bug 1420303 - Free memory between DAMP test to reduce its noise factor. r=jdescottes draft
authorAlexandre Poirot <poirot.alex@gmail.com>
Thu, 23 Nov 2017 09:10:00 -0800
changeset 705555 7d7d2ffd3cb20c8b73849ef582ba5728dd4b6278
parent 705554 8615d051a88c0406fc6f599e3f8576e68e14f643
child 742401 316ce8ba53e46bbc726eb19e3861f07bfda1282d
push id91519
push userbmo:poirot.alex@gmail.com
push dateThu, 30 Nov 2017 10:53:46 +0000
reviewersjdescottes
bugs1420303
milestone59.0a1
Bug 1420303 - Free memory between DAMP test to reduce its noise factor. r=jdescottes Doing one GC before running all test prevent having one running during the first test. Doing another on test teardown prevent getting another during next subtests. And finally, doing a last one after toolbox opening prevent a major GC from running during reload tests (especially "complicated" ones). MozReview-Commit-ID: 5hkSoCqNc9m
testing/talos/talos/tests/devtools/addon/content/damp.js
--- a/testing/talos/talos/tests/devtools/addon/content/damp.js
+++ b/testing/talos/talos/tests/devtools/addon/content/damp.js
@@ -1,10 +1,11 @@
 const { Services } = Components.utils.import("resource://gre/modules/Services.jsm", {});
 const { XPCOMUtils } = Cu.import("resource://gre/modules/XPCOMUtils.jsm", {});
+const gMgr = Cc["@mozilla.org/memory-reporter-manager;1"].getService(Ci.nsIMemoryReporterManager);
 
 XPCOMUtils.defineLazyGetter(this, "require", function() {
   let { require } =
     Components.utils.import("resource://devtools/shared/Loader.jsm", {});
   return require;
 });
 XPCOMUtils.defineLazyGetter(this, "gDevTools", function() {
   let { gDevTools } = require("devtools/client/framework/devtools");
@@ -31,16 +32,36 @@ const CUSTOM_URL = webserver + "/tests/d
 function getMostRecentBrowserWindow() {
   return Services.wm.getMostRecentWindow("navigator:browser");
 }
 
 function getActiveTab(window) {
   return window.gBrowser.selectedTab;
 }
 
+async function garbageCollect() {
+  dump("Garbage collect\n");
+
+  // Minimize memory usage
+  // mimic miminizeMemoryUsage, by only flushing JS objects via GC.
+  // We don't want to flush all the cache like minimizeMemoryUsage,
+  // as it slow down next executions almost like a cold start.
+
+  // See minimizeMemoryUsage code to justify the 3 iterations and the setTimeout:
+  // https://searchfox.org/mozilla-central/source/xpcom/base/nsMemoryReporterManager.cpp#2574-2585
+  for (let i = 0; i < 3; i++) {
+    // See minimizeMemoryUsage code here to justify the GC+CC+GC:
+    // https://searchfox.org/mozilla-central/rev/be78e6ea9b10b1f5b2b3b013f01d86e1062abb2b/dom/base/nsJSEnvironment.cpp#341-349
+    Cu.forceGC();
+    Cu.forceCC();
+    Cu.forceGC();
+    await new Promise(done => setTimeout(done, 0));
+  }
+}
+
 /* globals res:true */
 
 function Damp() {
   // Path to the temp file where the heap snapshot file is saved. Set by
   // saveHeapSnapshot and read by readHeapSnapshot.
   this._heapSnapshotFilePath = null;
   // HeapSnapshot instance. Set by readHeapSnapshot, used by takeCensus.
   this._snapshot = null;
@@ -459,16 +480,21 @@ async _consoleOpenWithCachedMessagesTest
     return Promise.resolve();
   },
 
   async openToolboxAndLog(name, tool, onLoad) {
     dump("Open toolbox on '" + name + "'\n");
     let test = this.runTest(name + ".open.DAMP");
     let toolbox = await this.openToolbox(tool, onLoad);
     test.done();
+
+    // Force freeing memory after toolbox open as it creates a lot of objects
+    // and for complex documents, it introduces a GC that runs during 'reload' test.
+    await garbageCollect();
+
     return toolbox;
   },
 
   async closeToolboxAndLog(name) {
     dump("Close toolbox on '" + name + "'\n");
     let tab = getActiveTab(getMostRecentBrowserWindow());
     let target = TargetFactory.forTab(tab);
     await target.client.waitForRequestsToSettle();
@@ -651,16 +677,20 @@ async _consoleOpenWithCachedMessagesTest
     await new Promise(resolve => {
       setTimeout(resolve, this._config.rest);
     });
     return tab;
   },
 
   async testTeardown(url) {
     this.closeCurrentTab();
+
+    // Force freeing memory now so that it doesn't happen during the next test
+    await garbageCollect();
+
     this._nextCommand();
   },
 
   // Everything below here are common pieces needed for the test runner to function,
   // just copy and pasted from Tart with /s/TART/DAMP
 
   _win: undefined,
   _dampTab: undefined,
@@ -856,11 +886,15 @@ async _consoleOpenWithCachedMessagesTest
         if (!config.subtests[i] || !tests[config.subtests[i]]) {
           continue;
         }
 
         sequenceArray.push(tests[config.subtests[i]]);
       }
     }
 
-    this._doSequence(sequenceArray, this._doneInternal);
+    // Free memory before running the first test, otherwise we may have a GC
+    // related to Firefox startup or DAMP setup during the first test.
+    garbageCollect().then(() => {
+      this._doSequence(sequenceArray, this._doneInternal);
+    });
   }
 };