[or-cvs] r19752: {torctl} Add a routine to check reference counts of all class instanc (torctl/trunk/python/TorCtl)

mikeperry at seul.org mikeperry at seul.org
Sun Jun 21 02:49:56 UTC 2009


Author: mikeperry
Date: 2009-06-20 22:49:56 -0400 (Sat, 20 Jun 2009)
New Revision: 19752

Modified:
   torctl/trunk/python/TorCtl/TorUtil.py
Log:

Add a routine to check reference counts of all class
instances and produce stats on which classes hold them
to help narrow in on why our memory usage keeps going 
up over time.



Modified: torctl/trunk/python/TorCtl/TorUtil.py
===================================================================
--- torctl/trunk/python/TorCtl/TorUtil.py	2009-06-21 02:48:02 UTC (rev 19751)
+++ torctl/trunk/python/TorCtl/TorUtil.py	2009-06-21 02:49:56 UTC (rev 19752)
@@ -32,6 +32,52 @@
 meta_port = 9052
 meta_host = '127.0.0.1'
 
+def dump_class_ref_counts(track_referers=True, cutoff=100, rcutoff=1,
+        ignore=('tuple', 'list', 'function', 'dict',
+                 'builtin_function_or_method')):
+  """ Debugging function to track down types of objects
+      that cannot be garbage collected because we hold refs to them 
+      somewhere."""
+  import gc
+  __dump_class_ref_counts(gc, track_referers, cutoff, rcutoff, ignore)
+  gc.collect()
+  plog("NOTICE", "GC: Done.")
+
+def __dump_class_ref_counts(gc, referers, cutoff, rcutoff, ignore):
+  """ loil
+  """
+  plog("NOTICE", "GC: Gathering garbage collection stats...")
+  uncollectable = gc.collect()
+  class_counts = {}
+  ref_counts = {}
+  plog("NOTICE", "GC: Uncollectable objects: "+str(uncollectable))
+  for obj in gc.get_objects():
+    if hasattr(obj, "__class__"):
+      cl = obj.__class__.__name__
+      if cl in ignore: continue
+      if cl not in class_counts:
+        class_counts[cl] = 0
+      class_counts[cl] += 1
+      if referers:
+        for r in gc.get_referrers(obj):
+          if hasattr(r, "__class__"):
+            if cl not in ref_counts:
+              ref_counts[cl] = {}
+            if r.__class__.__name__ not in ref_counts[cl]:
+              ref_counts[cl][r.__class__.__name__] = 0
+            ref_counts[cl][r.__class__.__name__] += 1
+  classes = class_counts.keys()
+  classes.sort(lambda x, y: class_counts[y] - class_counts[x])
+  for c in classes:
+    if class_counts[c] < cutoff: continue
+    plog("NOTICE", "GC: Class "+c+": "+str(class_counts[c]))
+    if referers:
+      refs = ref_counts[c].keys()
+      refs.sort(lambda x, y: ref_counts[c][y] - ref_counts[c][x])
+      for r in refs:
+        if ref_counts[c][r] < rcutoff: continue
+        plog("NOTICE", "GC:   Refed by "+r+": "+str(ref_counts[c][r]))
+
 def read_config(filename):
   config = ConfigParser.SafeConfigParser()
   config.read(filename)



More information about the tor-commits mailing list