|
1 |
|
2 import gc, types, weakref |
|
3 |
|
4 from cubicweb.schema import CubicWebRelationSchema, CubicWebEntitySchema |
|
5 |
|
6 listiterator = type(iter([])) |
|
7 |
|
8 IGNORE_CLASSES = ( |
|
9 type, tuple, dict, list, set, frozenset, type(len), |
|
10 weakref.ref, weakref.WeakKeyDictionary, |
|
11 listiterator, |
|
12 property, classmethod, |
|
13 types.ModuleType, types.FunctionType, types.MethodType, |
|
14 types.MemberDescriptorType, types.GetSetDescriptorType, |
|
15 ) |
|
16 |
|
17 def _get_counted_class(obj, classes): |
|
18 for cls in classes: |
|
19 if isinstance(obj, cls): |
|
20 return cls |
|
21 raise AssertionError() |
|
22 |
|
23 def gc_info(countclasses, |
|
24 ignoreclasses=IGNORE_CLASSES, |
|
25 viewreferrersclasses=(), showobjs=False): |
|
26 gc.collect() |
|
27 gc.collect() |
|
28 counters = {} |
|
29 ocounters = {} |
|
30 for obj in gc.get_objects(): |
|
31 if isinstance(obj, countclasses): |
|
32 cls = _get_counted_class(obj, countclasses) |
|
33 try: |
|
34 counters[cls.__name__] += 1 |
|
35 except KeyError: |
|
36 counters[cls.__name__] = 1 |
|
37 elif not isinstance(obj, ignoreclasses): |
|
38 try: |
|
39 key = '%s.%s' % (obj.__class__.__module__, |
|
40 obj.__class__.__name__) |
|
41 except AttributeError: |
|
42 key = str(obj) |
|
43 try: |
|
44 ocounters[key] += 1 |
|
45 except KeyError: |
|
46 ocounters[key] = 1 |
|
47 if isinstance(obj, viewreferrersclasses): |
|
48 print ' ', obj, referrers(obj, showobjs) |
|
49 return counters, ocounters, gc.garbage |
|
50 |
|
51 |
|
52 def referrers(obj, showobj=False, maxlevel=1): |
|
53 objreferrers = _referrers(obj, maxlevel) |
|
54 try: |
|
55 return sorted(set((type(x), showobj and x or getattr(x, '__name__', '%#x' % id(x))) |
|
56 for x in objreferrers)) |
|
57 except TypeError: |
|
58 s = set() |
|
59 unhashable = [] |
|
60 for x in objreferrers: |
|
61 try: |
|
62 s.add(x) |
|
63 except TypeError: |
|
64 unhashable.append(x) |
|
65 return sorted(s) + unhashable |
|
66 |
|
67 def _referrers(obj, maxlevel, _seen=None, _level=0): |
|
68 interesting = [] |
|
69 if _seen is None: |
|
70 _seen = set() |
|
71 for x in gc.get_referrers(obj): |
|
72 if id(x) in _seen: |
|
73 continue |
|
74 _seen.add(id(x)) |
|
75 if isinstance(x, types.FrameType): |
|
76 continue |
|
77 if isinstance(x, (CubicWebRelationSchema, CubicWebEntitySchema)): |
|
78 continue |
|
79 if isinstance(x, (list, tuple, set, dict, listiterator)): |
|
80 if _level >= maxlevel: |
|
81 pass |
|
82 #interesting.append(x) |
|
83 else: |
|
84 interesting += _referrers(x, maxlevel, _seen, _level+1) |
|
85 else: |
|
86 interesting.append(x) |
|
87 return interesting |