Mercurial > js4py
annotate source/counters-memory.rst @ 162:77e87f1b5811 core-javascript
$ hg merge core-javascript.closure-exercises # done, at least for now
| author | jf3243 |
|---|---|
| date | Wed, 09 Nov 2011 17:00:38 +0000 |
| parents | cfb78eef6a57 |
| children | 4e6cfa066d1a |
| rev | line source |
|---|---|
|
62
3a7abcc737f8
counters-memory.rst: Removed material belonging to counters-discuss.rst.
Jonathan Fine <jfine@pytex.org>
parents:
60
diff
changeset
|
1 Counters memory |
|
3a7abcc737f8
counters-memory.rst: Removed material belonging to counters-discuss.rst.
Jonathan Fine <jfine@pytex.org>
parents:
60
diff
changeset
|
2 =============== |
|
37
2dd438e80b7b
counters-example.rst: Added 'Closing namespace' and 'Memory' sections.
Jonathan Fine <jfine@pytex.org>
parents:
36
diff
changeset
|
3 |
|
2dd438e80b7b
counters-example.rst: Added 'Closing namespace' and 'Memory' sections.
Jonathan Fine <jfine@pytex.org>
parents:
36
diff
changeset
|
4 Memory |
|
2dd438e80b7b
counters-example.rst: Added 'Closing namespace' and 'Memory' sections.
Jonathan Fine <jfine@pytex.org>
parents:
36
diff
changeset
|
5 ------ |
|
2dd438e80b7b
counters-example.rst: Added 'Closing namespace' and 'Memory' sections.
Jonathan Fine <jfine@pytex.org>
parents:
36
diff
changeset
|
6 |
|
2dd438e80b7b
counters-example.rst: Added 'Closing namespace' and 'Memory' sections.
Jonathan Fine <jfine@pytex.org>
parents:
36
diff
changeset
|
7 Understanding garbage collection and memory leaks is an advanced |
|
2dd438e80b7b
counters-example.rst: Added 'Closing namespace' and 'Memory' sections.
Jonathan Fine <jfine@pytex.org>
parents:
36
diff
changeset
|
8 topic, but even beginners should know that there can be problems here. |
|
2dd438e80b7b
counters-example.rst: Added 'Closing namespace' and 'Memory' sections.
Jonathan Fine <jfine@pytex.org>
parents:
36
diff
changeset
|
9 Correct use of a suitable framework is the simplest way to avoid |
|
2dd438e80b7b
counters-example.rst: Added 'Closing namespace' and 'Memory' sections.
Jonathan Fine <jfine@pytex.org>
parents:
36
diff
changeset
|
10 memory leaks. |
|
2dd438e80b7b
counters-example.rst: Added 'Closing namespace' and 'Memory' sections.
Jonathan Fine <jfine@pytex.org>
parents:
36
diff
changeset
|
11 |
|
63
cfb78eef6a57
counters-memory.rst: Major revisions. Now good enough,
Jonathan Fine <jfine@pytex.org>
parents:
62
diff
changeset
|
12 The code in the counters example indicates how to construct and use such |
|
37
2dd438e80b7b
counters-example.rst: Added 'Closing namespace' and 'Memory' sections.
Jonathan Fine <jfine@pytex.org>
parents:
36
diff
changeset
|
13 a framework. |
|
2dd438e80b7b
counters-example.rst: Added 'Closing namespace' and 'Memory' sections.
Jonathan Fine <jfine@pytex.org>
parents:
36
diff
changeset
|
14 |
|
63
cfb78eef6a57
counters-memory.rst: Major revisions. Now good enough,
Jonathan Fine <jfine@pytex.org>
parents:
62
diff
changeset
|
15 IE memory leaks |
|
cfb78eef6a57
counters-memory.rst: Major revisions. Now good enough,
Jonathan Fine <jfine@pytex.org>
parents:
62
diff
changeset
|
16 --------------- |
|
cfb78eef6a57
counters-memory.rst: Major revisions. Now good enough,
Jonathan Fine <jfine@pytex.org>
parents:
62
diff
changeset
|
17 |
|
cfb78eef6a57
counters-memory.rst: Major revisions. Now good enough,
Jonathan Fine <jfine@pytex.org>
parents:
62
diff
changeset
|
18 Internet Explorer, prior to IE8 (check) had **two memory heaps**, one |
|
cfb78eef6a57
counters-memory.rst: Major revisions. Now good enough,
Jonathan Fine <jfine@pytex.org>
parents:
62
diff
changeset
|
19 for JavaScript and the other for the DOM. Each heap had its own |
|
cfb78eef6a57
counters-memory.rst: Major revisions. Now good enough,
Jonathan Fine <jfine@pytex.org>
parents:
62
diff
changeset
|
20 independent garbage collector. |
|
cfb78eef6a57
counters-memory.rst: Major revisions. Now good enough,
Jonathan Fine <jfine@pytex.org>
parents:
62
diff
changeset
|
21 |
|
cfb78eef6a57
counters-memory.rst: Major revisions. Now good enough,
Jonathan Fine <jfine@pytex.org>
parents:
62
diff
changeset
|
22 This means that if a DOM node *d* held a reference to a JavaScript |
|
cfb78eef6a57
counters-memory.rst: Major revisions. Now good enough,
Jonathan Fine <jfine@pytex.org>
parents:
62
diff
changeset
|
23 object *j* and also that *j* held a reference to *d* then neither |
|
cfb78eef6a57
counters-memory.rst: Major revisions. Now good enough,
Jonathan Fine <jfine@pytex.org>
parents:
62
diff
changeset
|
24 garbage collector could collect *j* or *d*. What's worse, even when |
|
cfb78eef6a57
counters-memory.rst: Major revisions. Now good enough,
Jonathan Fine <jfine@pytex.org>
parents:
62
diff
changeset
|
25 the page was unloaded IE did not reclaim this memory. |
|
cfb78eef6a57
counters-memory.rst: Major revisions. Now good enough,
Jonathan Fine <jfine@pytex.org>
parents:
62
diff
changeset
|
26 |
|
cfb78eef6a57
counters-memory.rst: Major revisions. Now good enough,
Jonathan Fine <jfine@pytex.org>
parents:
62
diff
changeset
|
27 Thus, prior to IE8, JavaScript could cause Internet Explorer to leak |
|
cfb78eef6a57
counters-memory.rst: Major revisions. Now good enough,
Jonathan Fine <jfine@pytex.org>
parents:
62
diff
changeset
|
28 memory. This lost memory could be reclaimed only by closing the |
|
cfb78eef6a57
counters-memory.rst: Major revisions. Now good enough,
Jonathan Fine <jfine@pytex.org>
parents:
62
diff
changeset
|
29 browser! Closing the page was not enough. |
|
cfb78eef6a57
counters-memory.rst: Major revisions. Now good enough,
Jonathan Fine <jfine@pytex.org>
parents:
62
diff
changeset
|
30 |
|
37
2dd438e80b7b
counters-example.rst: Added 'Closing namespace' and 'Memory' sections.
Jonathan Fine <jfine@pytex.org>
parents:
36
diff
changeset
|
31 Garbage collection |
|
59
5bec62c76e8b
counters-discuss.rst: Added editorial changes and some additional content.
Jonathan Fine <jfine@pytex.org>
parents:
56
diff
changeset
|
32 ------------------ |
|
37
2dd438e80b7b
counters-example.rst: Added 'Closing namespace' and 'Memory' sections.
Jonathan Fine <jfine@pytex.org>
parents:
36
diff
changeset
|
33 The JavaScript garbage collection deletes objects provide it can |
|
2dd438e80b7b
counters-example.rst: Added 'Closing namespace' and 'Memory' sections.
Jonathan Fine <jfine@pytex.org>
parents:
36
diff
changeset
|
34 discover that they can never be used again. The simplest case is: |
|
2dd438e80b7b
counters-example.rst: Added 'Closing namespace' and 'Memory' sections.
Jonathan Fine <jfine@pytex.org>
parents:
36
diff
changeset
|
35 |
|
2dd438e80b7b
counters-example.rst: Added 'Closing namespace' and 'Memory' sections.
Jonathan Fine <jfine@pytex.org>
parents:
36
diff
changeset
|
36 .. code-block:: javascript |
|
2dd438e80b7b
counters-example.rst: Added 'Closing namespace' and 'Memory' sections.
Jonathan Fine <jfine@pytex.org>
parents:
36
diff
changeset
|
37 |
|
2dd438e80b7b
counters-example.rst: Added 'Closing namespace' and 'Memory' sections.
Jonathan Fine <jfine@pytex.org>
parents:
36
diff
changeset
|
38 x = [1, 2, 3, 4, 5, 6, 7]; |
|
2dd438e80b7b
counters-example.rst: Added 'Closing namespace' and 'Memory' sections.
Jonathan Fine <jfine@pytex.org>
parents:
36
diff
changeset
|
39 x = null; |
|
2dd438e80b7b
counters-example.rst: Added 'Closing namespace' and 'Memory' sections.
Jonathan Fine <jfine@pytex.org>
parents:
36
diff
changeset
|
40 |
|
2dd438e80b7b
counters-example.rst: Added 'Closing namespace' and 'Memory' sections.
Jonathan Fine <jfine@pytex.org>
parents:
36
diff
changeset
|
41 The second assignment to *x* ensures that the original array (created |
|
2dd438e80b7b
counters-example.rst: Added 'Closing namespace' and 'Memory' sections.
Jonathan Fine <jfine@pytex.org>
parents:
36
diff
changeset
|
42 by the array literal) can no longer be accessed, and so it can be |
|
2dd438e80b7b
counters-example.rst: Added 'Closing namespace' and 'Memory' sections.
Jonathan Fine <jfine@pytex.org>
parents:
36
diff
changeset
|
43 garbage collected. |
|
2dd438e80b7b
counters-example.rst: Added 'Closing namespace' and 'Memory' sections.
Jonathan Fine <jfine@pytex.org>
parents:
36
diff
changeset
|
44 |
|
63
cfb78eef6a57
counters-memory.rst: Major revisions. Now good enough,
Jonathan Fine <jfine@pytex.org>
parents:
62
diff
changeset
|
45 After the counters namespace anonyomous function has executed there |
|
cfb78eef6a57
counters-memory.rst: Major revisions. Now good enough,
Jonathan Fine <jfine@pytex.org>
parents:
62
diff
changeset
|
46 are no global objects holding even indirect references to the |
|
cfb78eef6a57
counters-memory.rst: Major revisions. Now good enough,
Jonathan Fine <jfine@pytex.org>
parents:
62
diff
changeset
|
47 function. Therefore it can and will be garbage collected. However, as |
|
cfb78eef6a57
counters-memory.rst: Major revisions. Now good enough,
Jonathan Fine <jfine@pytex.org>
parents:
62
diff
changeset
|
48 we shall see, the execution context of the function continues. |
|
37
2dd438e80b7b
counters-example.rst: Added 'Closing namespace' and 'Memory' sections.
Jonathan Fine <jfine@pytex.org>
parents:
36
diff
changeset
|
49 |
|
63
cfb78eef6a57
counters-memory.rst: Major revisions. Now good enough,
Jonathan Fine <jfine@pytex.org>
parents:
62
diff
changeset
|
50 The whole of the discussion here reduces to two things |
|
cfb78eef6a57
counters-memory.rst: Major revisions. Now good enough,
Jonathan Fine <jfine@pytex.org>
parents:
62
diff
changeset
|
51 |
|
cfb78eef6a57
counters-memory.rst: Major revisions. Now good enough,
Jonathan Fine <jfine@pytex.org>
parents:
62
diff
changeset
|
52 * The execution of the context of the namespace anonymous function |
|
cfb78eef6a57
counters-memory.rst: Major revisions. Now good enough,
Jonathan Fine <jfine@pytex.org>
parents:
62
diff
changeset
|
53 continues to exist after the function has completed execution. |
|
cfb78eef6a57
counters-memory.rst: Major revisions. Now good enough,
Jonathan Fine <jfine@pytex.org>
parents:
62
diff
changeset
|
54 |
|
cfb78eef6a57
counters-memory.rst: Major revisions. Now good enough,
Jonathan Fine <jfine@pytex.org>
parents:
62
diff
changeset
|
55 * If the line |
|
37
2dd438e80b7b
counters-example.rst: Added 'Closing namespace' and 'Memory' sections.
Jonathan Fine <jfine@pytex.org>
parents:
36
diff
changeset
|
56 |
|
63
cfb78eef6a57
counters-memory.rst: Major revisions. Now good enough,
Jonathan Fine <jfine@pytex.org>
parents:
62
diff
changeset
|
57 .. code-block: javascript |
|
cfb78eef6a57
counters-memory.rst: Major revisions. Now good enough,
Jonathan Fine <jfine@pytex.org>
parents:
62
diff
changeset
|
58 element.onclick = onclick_factory(models); |
|
cfb78eef6a57
counters-memory.rst: Major revisions. Now good enough,
Jonathan Fine <jfine@pytex.org>
parents:
62
diff
changeset
|
59 |
|
cfb78eef6a57
counters-memory.rst: Major revisions. Now good enough,
Jonathan Fine <jfine@pytex.org>
parents:
62
diff
changeset
|
60 were replaced by |
|
36
ba6a69b59573
counters-example.rst: Broke source display into chunks.
Jonathan Fine <jfine@pytex.org>
parents:
33
diff
changeset
|
61 |
|
63
cfb78eef6a57
counters-memory.rst: Major revisions. Now good enough,
Jonathan Fine <jfine@pytex.org>
parents:
62
diff
changeset
|
62 .. code-block: javascript |
|
cfb78eef6a57
counters-memory.rst: Major revisions. Now good enough,
Jonathan Fine <jfine@pytex.org>
parents:
62
diff
changeset
|
63 element.onclick = onclick_factory(models); |
|
37
2dd438e80b7b
counters-example.rst: Added 'Closing namespace' and 'Memory' sections.
Jonathan Fine <jfine@pytex.org>
parents:
36
diff
changeset
|
64 |
|
63
cfb78eef6a57
counters-memory.rst: Major revisions. Now good enough,
Jonathan Fine <jfine@pytex.org>
parents:
62
diff
changeset
|
65 then after the execution of the namespace anonymous function all the |
|
cfb78eef6a57
counters-memory.rst: Major revisions. Now good enough,
Jonathan Fine <jfine@pytex.org>
parents:
62
diff
changeset
|
66 JavaScript objects it created would be garbage collected. |
|
cfb78eef6a57
counters-memory.rst: Major revisions. Now good enough,
Jonathan Fine <jfine@pytex.org>
parents:
62
diff
changeset
|
67 |
|
cfb78eef6a57
counters-memory.rst: Major revisions. Now good enough,
Jonathan Fine <jfine@pytex.org>
parents:
62
diff
changeset
|
68 The trick is to allow garbage collection to take place by releasing, |
|
cfb78eef6a57
counters-memory.rst: Major revisions. Now good enough,
Jonathan Fine <jfine@pytex.org>
parents:
62
diff
changeset
|
69 when the time comes, all DOM reference to JavaScript objects. |
|
37
2dd438e80b7b
counters-example.rst: Added 'Closing namespace' and 'Memory' sections.
Jonathan Fine <jfine@pytex.org>
parents:
36
diff
changeset
|
70 |
|
2dd438e80b7b
counters-example.rst: Added 'Closing namespace' and 'Memory' sections.
Jonathan Fine <jfine@pytex.org>
parents:
36
diff
changeset
|
71 Residue |
|
59
5bec62c76e8b
counters-discuss.rst: Added editorial changes and some additional content.
Jonathan Fine <jfine@pytex.org>
parents:
56
diff
changeset
|
72 ------- |
|
37
2dd438e80b7b
counters-example.rst: Added 'Closing namespace' and 'Memory' sections.
Jonathan Fine <jfine@pytex.org>
parents:
36
diff
changeset
|
73 |
|
63
cfb78eef6a57
counters-memory.rst: Major revisions. Now good enough,
Jonathan Fine <jfine@pytex.org>
parents:
62
diff
changeset
|
74 The *element* DOM node continues to exist, as it can be reached from |
|
37
2dd438e80b7b
counters-example.rst: Added 'Closing namespace' and 'Memory' sections.
Jonathan Fine <jfine@pytex.org>
parents:
36
diff
changeset
|
75 the *document* node. It has an *onclick* attribute, which is the |
|
2dd438e80b7b
counters-example.rst: Added 'Closing namespace' and 'Memory' sections.
Jonathan Fine <jfine@pytex.org>
parents:
36
diff
changeset
|
76 function created by the *onclick_factory*, with *models* as the |
|
63
cfb78eef6a57
counters-memory.rst: Major revisions. Now good enough,
Jonathan Fine <jfine@pytex.org>
parents:
62
diff
changeset
|
77 argument. So that function is not garbage collected and neither is |
|
cfb78eef6a57
counters-memory.rst: Major revisions. Now good enough,
Jonathan Fine <jfine@pytex.org>
parents:
62
diff
changeset
|
78 *models*. |
|
37
2dd438e80b7b
counters-example.rst: Added 'Closing namespace' and 'Memory' sections.
Jonathan Fine <jfine@pytex.org>
parents:
36
diff
changeset
|
79 |
|
63
cfb78eef6a57
counters-memory.rst: Major revisions. Now good enough,
Jonathan Fine <jfine@pytex.org>
parents:
62
diff
changeset
|
80 This is just as it should be. Anything that can be reached from the |
|
cfb78eef6a57
counters-memory.rst: Major revisions. Now good enough,
Jonathan Fine <jfine@pytex.org>
parents:
62
diff
changeset
|
81 rendered web page is not garbage collected. It has to be there so |
|
cfb78eef6a57
counters-memory.rst: Major revisions. Now good enough,
Jonathan Fine <jfine@pytex.org>
parents:
62
diff
changeset
|
82 that click has the desired effect. |
|
cfb78eef6a57
counters-memory.rst: Major revisions. Now good enough,
Jonathan Fine <jfine@pytex.org>
parents:
62
diff
changeset
|
83 |
|
cfb78eef6a57
counters-memory.rst: Major revisions. Now good enough,
Jonathan Fine <jfine@pytex.org>
parents:
62
diff
changeset
|
84 The function *element.onclick* retains a reference to *models* just as |
|
37
2dd438e80b7b
counters-example.rst: Added 'Closing namespace' and 'Memory' sections.
Jonathan Fine <jfine@pytex.org>
parents:
36
diff
changeset
|
85 surely as executing |
|
2dd438e80b7b
counters-example.rst: Added 'Closing namespace' and 'Memory' sections.
Jonathan Fine <jfine@pytex.org>
parents:
36
diff
changeset
|
86 |
|
2dd438e80b7b
counters-example.rst: Added 'Closing namespace' and 'Memory' sections.
Jonathan Fine <jfine@pytex.org>
parents:
36
diff
changeset
|
87 .. code-block:: javascript |
|
2dd438e80b7b
counters-example.rst: Added 'Closing namespace' and 'Memory' sections.
Jonathan Fine <jfine@pytex.org>
parents:
36
diff
changeset
|
88 |
|
2dd438e80b7b
counters-example.rst: Added 'Closing namespace' and 'Memory' sections.
Jonathan Fine <jfine@pytex.org>
parents:
36
diff
changeset
|
89 var f = function(arg){ return [1, 2, 3, arg] }; |
|
2dd438e80b7b
counters-example.rst: Added 'Closing namespace' and 'Memory' sections.
Jonathan Fine <jfine@pytex.org>
parents:
36
diff
changeset
|
90 var y = f(x); |
|
2dd438e80b7b
counters-example.rst: Added 'Closing namespace' and 'Memory' sections.
Jonathan Fine <jfine@pytex.org>
parents:
36
diff
changeset
|
91 |
|
2dd438e80b7b
counters-example.rst: Added 'Closing namespace' and 'Memory' sections.
Jonathan Fine <jfine@pytex.org>
parents:
36
diff
changeset
|
92 causes *y* to retain a reference to the value of *x*. |
|
2dd438e80b7b
counters-example.rst: Added 'Closing namespace' and 'Memory' sections.
Jonathan Fine <jfine@pytex.org>
parents:
36
diff
changeset
|
93 |
|
2dd438e80b7b
counters-example.rst: Added 'Closing namespace' and 'Memory' sections.
Jonathan Fine <jfine@pytex.org>
parents:
36
diff
changeset
|
94 Finally, *models* contains references to the *Counter* instances and |
|
2dd438e80b7b
counters-example.rst: Added 'Closing namespace' and 'Memory' sections.
Jonathan Fine <jfine@pytex.org>
parents:
36
diff
changeset
|
95 thus, by the hidden prototype reference, to the *counter* prototype |
|
2dd438e80b7b
counters-example.rst: Added 'Closing namespace' and 'Memory' sections.
Jonathan Fine <jfine@pytex.org>
parents:
36
diff
changeset
|
96 object. |
|
2dd438e80b7b
counters-example.rst: Added 'Closing namespace' and 'Memory' sections.
Jonathan Fine <jfine@pytex.org>
parents:
36
diff
changeset
|
97 |
|
2dd438e80b7b
counters-example.rst: Added 'Closing namespace' and 'Memory' sections.
Jonathan Fine <jfine@pytex.org>
parents:
36
diff
changeset
|
98 The *counter* prototype object lies in the execution context of the |
|
2dd438e80b7b
counters-example.rst: Added 'Closing namespace' and 'Memory' sections.
Jonathan Fine <jfine@pytex.org>
parents:
36
diff
changeset
|
99 anonymous function, and as it happend that keeps alive the whole of |
|
2dd438e80b7b
counters-example.rst: Added 'Closing namespace' and 'Memory' sections.
Jonathan Fine <jfine@pytex.org>
parents:
36
diff
changeset
|
100 the execution context. |
|
2dd438e80b7b
counters-example.rst: Added 'Closing namespace' and 'Memory' sections.
Jonathan Fine <jfine@pytex.org>
parents:
36
diff
changeset
|
101 |
|
2dd438e80b7b
counters-example.rst: Added 'Closing namespace' and 'Memory' sections.
Jonathan Fine <jfine@pytex.org>
parents:
36
diff
changeset
|
102 Reclaiming memory |
|
59
5bec62c76e8b
counters-discuss.rst: Added editorial changes and some additional content.
Jonathan Fine <jfine@pytex.org>
parents:
56
diff
changeset
|
103 ----------------- |
|
37
2dd438e80b7b
counters-example.rst: Added 'Closing namespace' and 'Memory' sections.
Jonathan Fine <jfine@pytex.org>
parents:
36
diff
changeset
|
104 |
|
2dd438e80b7b
counters-example.rst: Added 'Closing namespace' and 'Memory' sections.
Jonathan Fine <jfine@pytex.org>
parents:
36
diff
changeset
|
105 Notice that the JavaScript holds only two reference to DOM nodes, |
|
2dd438e80b7b
counters-example.rst: Added 'Closing namespace' and 'Memory' sections.
Jonathan Fine <jfine@pytex.org>
parents:
36
diff
changeset
|
106 namely *document* and *example*. However, the line of code |
|
2dd438e80b7b
counters-example.rst: Added 'Closing namespace' and 'Memory' sections.
Jonathan Fine <jfine@pytex.org>
parents:
36
diff
changeset
|
107 |
|
2dd438e80b7b
counters-example.rst: Added 'Closing namespace' and 'Memory' sections.
Jonathan Fine <jfine@pytex.org>
parents:
36
diff
changeset
|
108 .. code-block:: javascript |
|
2dd438e80b7b
counters-example.rst: Added 'Closing namespace' and 'Memory' sections.
Jonathan Fine <jfine@pytex.org>
parents:
36
diff
changeset
|
109 |
|
63
cfb78eef6a57
counters-memory.rst: Major revisions. Now good enough,
Jonathan Fine <jfine@pytex.org>
parents:
62
diff
changeset
|
110 element = undefined; // Release reference to DOM node. |
|
37
2dd438e80b7b
counters-example.rst: Added 'Closing namespace' and 'Memory' sections.
Jonathan Fine <jfine@pytex.org>
parents:
36
diff
changeset
|
111 |
|
63
cfb78eef6a57
counters-memory.rst: Major revisions. Now good enough,
Jonathan Fine <jfine@pytex.org>
parents:
62
diff
changeset
|
112 means that the JavaScript no longer holds a reference to *element*. |
|
37
2dd438e80b7b
counters-example.rst: Added 'Closing namespace' and 'Memory' sections.
Jonathan Fine <jfine@pytex.org>
parents:
36
diff
changeset
|
113 |
|
2dd438e80b7b
counters-example.rst: Added 'Closing namespace' and 'Memory' sections.
Jonathan Fine <jfine@pytex.org>
parents:
36
diff
changeset
|
114 The DOM node *example* holds a reference, via its *onclick* function, |
|
2dd438e80b7b
counters-example.rst: Added 'Closing namespace' and 'Memory' sections.
Jonathan Fine <jfine@pytex.org>
parents:
36
diff
changeset
|
115 to the JavaScript on the page, and in particular to the *Counter* |
|
2dd438e80b7b
counters-example.rst: Added 'Closing namespace' and 'Memory' sections.
Jonathan Fine <jfine@pytex.org>
parents:
36
diff
changeset
|
116 instances. This cannot be avoided, because we want certain DOM nodes |
|
2dd438e80b7b
counters-example.rst: Added 'Closing namespace' and 'Memory' sections.
Jonathan Fine <jfine@pytex.org>
parents:
36
diff
changeset
|
117 to change the state of the counters. |
|
2dd438e80b7b
counters-example.rst: Added 'Closing namespace' and 'Memory' sections.
Jonathan Fine <jfine@pytex.org>
parents:
36
diff
changeset
|
118 |
|
2dd438e80b7b
counters-example.rst: Added 'Closing namespace' and 'Memory' sections.
Jonathan Fine <jfine@pytex.org>
parents:
36
diff
changeset
|
119 However, the converse is not true. We can write the JavaScript code |
|
2dd438e80b7b
counters-example.rst: Added 'Closing namespace' and 'Memory' sections.
Jonathan Fine <jfine@pytex.org>
parents:
36
diff
changeset
|
120 so that it has but one reference to a DOM object, namely the |
|
2dd438e80b7b
counters-example.rst: Added 'Closing namespace' and 'Memory' sections.
Jonathan Fine <jfine@pytex.org>
parents:
36
diff
changeset
|
121 *document* node held for example as a property of the *global* object. |
|
63
cfb78eef6a57
counters-memory.rst: Major revisions. Now good enough,
Jonathan Fine <jfine@pytex.org>
parents:
62
diff
changeset
|
122 |
|
cfb78eef6a57
counters-memory.rst: Major revisions. Now good enough,
Jonathan Fine <jfine@pytex.org>
parents:
62
diff
changeset
|
123 Summary |
|
cfb78eef6a57
counters-memory.rst: Major revisions. Now good enough,
Jonathan Fine <jfine@pytex.org>
parents:
62
diff
changeset
|
124 ------- |
|
cfb78eef6a57
counters-memory.rst: Major revisions. Now good enough,
Jonathan Fine <jfine@pytex.org>
parents:
62
diff
changeset
|
125 |
|
cfb78eef6a57
counters-memory.rst: Major revisions. Now good enough,
Jonathan Fine <jfine@pytex.org>
parents:
62
diff
changeset
|
126 To avoid the IE memory leaks the trick is to ensure that, when the |
|
cfb78eef6a57
counters-memory.rst: Major revisions. Now good enough,
Jonathan Fine <jfine@pytex.org>
parents:
62
diff
changeset
|
127 page unloads, there is nothing that is keeping the garbage is alive. |
|
cfb78eef6a57
counters-memory.rst: Major revisions. Now good enough,
Jonathan Fine <jfine@pytex.org>
parents:
62
diff
changeset
|
128 If we execute |
|
cfb78eef6a57
counters-memory.rst: Major revisions. Now good enough,
Jonathan Fine <jfine@pytex.org>
parents:
62
diff
changeset
|
129 |
|
cfb78eef6a57
counters-memory.rst: Major revisions. Now good enough,
Jonathan Fine <jfine@pytex.org>
parents:
62
diff
changeset
|
130 .. code-block:: javascript |
|
cfb78eef6a57
counters-memory.rst: Major revisions. Now good enough,
Jonathan Fine <jfine@pytex.org>
parents:
62
diff
changeset
|
131 |
|
cfb78eef6a57
counters-memory.rst: Major revisions. Now good enough,
Jonathan Fine <jfine@pytex.org>
parents:
62
diff
changeset
|
132 element.onclick = undefined |
|
cfb78eef6a57
counters-memory.rst: Major revisions. Now good enough,
Jonathan Fine <jfine@pytex.org>
parents:
62
diff
changeset
|
133 |
|
cfb78eef6a57
counters-memory.rst: Major revisions. Now good enough,
Jonathan Fine <jfine@pytex.org>
parents:
62
diff
changeset
|
134 then there is nothing on the page that is keeping our JavaScript code |
|
cfb78eef6a57
counters-memory.rst: Major revisions. Now good enough,
Jonathan Fine <jfine@pytex.org>
parents:
62
diff
changeset
|
135 alive. And once all the JavaScript is garbage collected then there's |
|
cfb78eef6a57
counters-memory.rst: Major revisions. Now good enough,
Jonathan Fine <jfine@pytex.org>
parents:
62
diff
changeset
|
136 nothing to prevent all the DOM notde being garbage collected. |
|
cfb78eef6a57
counters-memory.rst: Major revisions. Now good enough,
Jonathan Fine <jfine@pytex.org>
parents:
62
diff
changeset
|
137 |
|
cfb78eef6a57
counters-memory.rst: Major revisions. Now good enough,
Jonathan Fine <jfine@pytex.org>
parents:
62
diff
changeset
|
138 The key principle in this strategy is that the page unload event |
|
cfb78eef6a57
counters-memory.rst: Major revisions. Now good enough,
Jonathan Fine <jfine@pytex.org>
parents:
62
diff
changeset
|
139 should unbind all JavaScript event handlers and other data attached to |
|
cfb78eef6a57
counters-memory.rst: Major revisions. Now good enough,
Jonathan Fine <jfine@pytex.org>
parents:
62
diff
changeset
|
140 the page. This will ensure that the JavaScript is garbage collected, |
|
cfb78eef6a57
counters-memory.rst: Major revisions. Now good enough,
Jonathan Fine <jfine@pytex.org>
parents:
62
diff
changeset
|
141 and hence there is nothing to obstruct garbage collection of the DOM |
|
cfb78eef6a57
counters-memory.rst: Major revisions. Now good enough,
Jonathan Fine <jfine@pytex.org>
parents:
62
diff
changeset
|
142 nodes. |
|
cfb78eef6a57
counters-memory.rst: Major revisions. Now good enough,
Jonathan Fine <jfine@pytex.org>
parents:
62
diff
changeset
|
143 |
|
cfb78eef6a57
counters-memory.rst: Major revisions. Now good enough,
Jonathan Fine <jfine@pytex.org>
parents:
62
diff
changeset
|
144 Clearly, this strategy requires us to keep track of what we add to the |
|
cfb78eef6a57
counters-memory.rst: Major revisions. Now good enough,
Jonathan Fine <jfine@pytex.org>
parents:
62
diff
changeset
|
145 DOM. Delegation makes this much easier to do. |
