addon-sdk/source/lib/sdk/deprecated/memory.js

changeset 0
6474c204b198
equal deleted inserted replaced
-1:000000000000 0:38874172c4ed
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 "use strict";
5
6 module.metadata = {
7 "stability": "deprecated"
8 };
9
10 const { Cc, Ci, Cu, components } = require("chrome");
11 const { when: unload } = require("../system/unload")
12
13 var trackedObjects = {};
14 const Compacter = {
15 notify: function() {
16 var newTrackedObjects = {};
17
18 for (let name in trackedObjects) {
19 let oldBin = trackedObjects[name];
20 let newBin = [];
21 let strongRefs = [];
22
23 for (let i = 0, l = oldBin.length; i < l; i++) {
24 let strongRef = oldBin[i].weakref.get();
25
26 if (strongRef && strongRefs.indexOf(strongRef) == -1) {
27 strongRefs.push(strongRef);
28 newBin.push(oldBin[i]);
29 }
30 }
31
32 if (newBin.length)
33 newTrackedObjects[name] = newBin;
34 }
35
36 trackedObjects = newTrackedObjects;
37 }
38 };
39
40 var timer = Cc["@mozilla.org/timer;1"]
41 .createInstance(Ci.nsITimer);
42 timer.initWithCallback(Compacter,
43 5000,
44 Ci.nsITimer.TYPE_REPEATING_SLACK);
45
46 function track(object, bin, stackFrameNumber) {
47 var frame = components.stack.caller;
48 var weakref = Cu.getWeakReference(object);
49
50 if (!bin && 'constructor' in object)
51 bin = object.constructor.name;
52 if (bin == "Object")
53 bin = frame.name;
54 if (!bin)
55 bin = "generic";
56 if (!(bin in trackedObjects))
57 trackedObjects[bin] = [];
58
59 if (stackFrameNumber > 0)
60 for (var i = 0; i < stackFrameNumber; i++)
61 frame = frame.caller;
62
63 trackedObjects[bin].push({weakref: weakref,
64 created: new Date(),
65 filename: frame.filename,
66 lineNo: frame.lineNumber,
67 bin: bin});
68 }
69 exports.track = track;
70
71 var getBins = exports.getBins = function getBins() {
72 var names = [];
73 for (let name in trackedObjects)
74 names.push(name);
75 return names;
76 };
77
78 function getObjects(bin) {
79 var results = [];
80
81 function getLiveObjectsInBin(bin) {
82 for (let i = 0, l = bin.length; i < l; i++) {
83 let object = bin[i].weakref.get();
84
85 if (object) {
86 results.push(bin[i]);
87 }
88 }
89 }
90
91 if (bin) {
92 if (bin in trackedObjects)
93 getLiveObjectsInBin(trackedObjects[bin]);
94 }
95 else {
96 for (let name in trackedObjects)
97 getLiveObjectsInBin(trackedObjects[name]);
98 }
99
100 return results;
101 }
102 exports.getObjects = getObjects;
103
104 function gc() {
105 // Components.utils.forceGC() doesn't currently perform
106 // cycle collection, which means that e.g. DOM elements
107 // won't be collected by it. Fortunately, there are
108 // other ways...
109 var test_utils = Cc["@mozilla.org/appshell/appShellService;1"]
110 .getService(Ci.nsIAppShellService)
111 .hiddenDOMWindow
112 .QueryInterface(Ci.nsIInterfaceRequestor)
113 .getInterface(Ci.nsIDOMWindowUtils);
114 test_utils.garbageCollect();
115 // Clean metadata for dead objects
116 Compacter.notify();
117 // Not sure why, but sometimes it appears that we don't get
118 // them all with just one CC, so let's do it again.
119 test_utils.garbageCollect();
120 };
121 exports.gc = gc;
122
123 unload(_ => {
124 trackedObjects = {};
125 if (timer) {
126 timer.cancel();
127 timer = null;
128 }
129 });

mercurial