@@ -173,7 +173,7 @@ The Power of Reference Counting
173173
174174* Objects get deleted right away
175175
176- . They get "cleaned up" (files, for instance)
176+ . They can "clean up" on deletion (files, for instance) -- and it will happen right away.
177177
178178* Performance is predictable
179179
@@ -187,7 +187,7 @@ The Limits of Reference Counting
187187
188188 Circular references
189189
190- If a python object references another object that references the first
190+ If a python object somehow references itself -- i.e. it references another object that references the first
191191object:
192192
193193You have a circular reference ...
@@ -196,42 +196,41 @@ You have a circular reference ...
196196Circular References
197197===================
198198
199- Circular Reference Example
200- --------------------------
199+ .. rst-class:: left
201200
202- .. code-block:: ipython
201+ .. code-block:: ipython
203202
204- In [8]: l1 = [1,] ; l2 = [2,]
203+ In [8]: l1 = [1,] ; l2 = [2,]
205204
206- In [9]: l1.append(l2); l2.append(l1)
205+ In [9]: l1.append(l2); l2.append(l1)
207206
208- In [10]: l1
209- Out[10]: [1, [2, [...]]]
207+ In [10]: l1
208+ Out[10]: [1, [2, [...]]]
210209
211- In [11]: l2
212- Out[11]: [2, [1, [...]]]
210+ In [11]: l2
211+ Out[11]: [2, [1, [...]]]
213212
214- In [12]: l1[1]
215- Out[12]: [2, [1, [...]]]
213+ In [12]: l1[1]
214+ Out[12]: [2, [1, [...]]]
216215
217- In [13]: l2[1][1][1]
218- Out[13]: [1, [2, [...]]]
216+ In [13]: l2[1][1][1]
217+ Out[13]: [1, [2, [...]]]
219218
220- In [16]: sys.getrefcount(l1)
221- Out[16]: 12
219+ (demo) -- :download:`simple_circular.py <../code/weak_references/simple_circular.py>`
222220
223221
224222The Garbage Collector
225- -----------------------
223+ ----------------------
226224
227225As of Python 2.0 -- a garbage collector was added.
228226
227+ - (https://docs.python.org/2/library/gc.html)
228+
229229It can find and clean up "unreachable" references.
230230
231231It is turned on by default::
232232
233233 In [1]: import gc
234-
235234 In [2]: gc.isenabled()
236235 Out[2]: True
237236
@@ -242,49 +241,124 @@ or you can force it::
242241
243242But it can be slow, and doesn't always work!
244243
245- Examples
244+ .. nextslide::
245+
246+ How does the garbage collector work?
247+
248+ * Not a full "mark and sweep" type.
249+
250+ It searches for reference cycles -- then cleans those up.
251+
252+ * It doesn't have to bother checking non-container types (ints, strings, etc.)
253+
254+ * Faster, and not as dependent on having a clear "root" namespace.
255+
256+ Details here:
257+
258+ http://arctrix.com/nas/python/gc/ (or in the source!)
259+
260+ Big issue: classes that define a ``__del__`` method are not cleaned up.
261+
262+ * ``__del__`` methods often act on references that may no be there if
263+ they are cleaned up in the wrong order.
264+
265+ NOTE: you can work with gc.garbage() -- but tricky and messy
266+
267+ =====
268+ Tools
269+ =====
270+
271+ .. rst-class:: left
272+
273+ If these objects are no longer "reachable" -- how do you find out what's going on?
274+
275+ We saw ``sys.getrefcount()`` -- but you need a reference to the object to use it.
276+
277+ You can see what the refcount is before you delete the last reference, but that isn't always easy.
278+
279+
280+ Process Memory Use
281+ -------------------
282+
283+ A really coarse way to find a memory leak is to see if the process memory
284+ is growing.
285+
286+ It can be subtle --python (and the OS) do tricks to re-use memory, etc.
287+
288+ But if you have a "real" leak -- you'll see it. (Example to follow)
289+
290+ :download:`mem_check.py <../code/weak_references/mem_check.py>`
291+
292+ provides functions that report the memory use of the current running process.
293+
294+ (\*nix and Windows code)
295+
296+ id checks
246297----------
247298
248- A really simple example:
299+ As it happens, the Python ``id()`` function returns a memory address.
249300
250- :download:`simple_circular.py <../code/weak_references/simple_circular.py>`
301+ It's really dangerous, but that means we can examine an object if we know
302+ its `id`, even if we don't hold a reference to it.
251303
304+ Bill Bumgarner wrote a nifty extension module that returns the python
305+ object pointed to by an id (memory address) -- "di":
252306
253- More real example in iPython notebook:
307+ http://www.friday.com/bbum/2007/08/24/python-di/
254308
255- :download:`CircularReferenceExample.ipynb <../code/weak_references/CircularReferenceExample.ipynb>`
309+ I added a function that returns the reference count of an object from its id.
256310
257- If you don't have the notebook running:
311+ https://github.com/PythonCHB/di_refcount
258312
259- :download:`circular.py <../ code/weak_references/circular.py>`
313+ NOTE: it would be a really bad idea to use these in production code!
260314
261- And :download:`memcount.py <../code/weak_references/memcount.py>` is a test
262- file that show memory growth if circular references are not cleaned up.
315+ Examples
316+ ----------
317+
318+ :download:`simple_circular_di.py <../code/weak_references/simple_circular_di.py>`
263319
320+ uses the ref_by_id() function to see what's going on with a circular
321+ reference and garbage collection.
322+
323+ More real examples in iPython notebook:
324+
325+ :download:`CircularReferenceExample.ipynb <../code/weak_references/CircularReferenceExample.ipynb>`
326+
327+ Or: :download:`circular.py <../code/weak_references/circular.py>`
328+
329+ :download:`memcount.py <../code/weak_references/memcount.py>` is a test
330+ file that show memory growth if circular references are not cleaned up.
264331
265332( :download:`mem_check.py <../code/weak_references/mem_check.py>` )
266333is code that reports process memory use.
267334
335+ You can find this code in the main repo here:
336+
337+ https://github.com/PythonCHB/PythonTopics/tree/master/Sources/code/weak_references
338+
268339
269340Weak References
270341-----------------
271342
272343For times when you don't want to keep objects alive, Python provides
273- "weak references".
344+ "weak references" -- we saw this in the examples .
274345
275- You saw this in the examples.
346+ (https://docs.python.org/2/library/weakref.html)
276347
277- Three ways to use them :
348+ 1. The built-in containers :
278349
279- * The built-in containers:
280350 - ``WeakKeyDictionary``
351+
281352 - ``WeakValueDictionary``
353+
282354 - ``WeakSet``
283355
284- * ``Proxy`` objects
356+ 2. ``Proxy`` objects
357+
285358 - act much like regular references -- client code doesn't know the difference
286359
287- * ``WeakRef`` objects
360+ 3. ``WeakRef`` objects
361+
288362 - When you want to control what happens when the referenced object is gone.
289363
290364=========
0 commit comments