def __len__(self): # do a garbage collection wasOn = gcDebugOn() oldFlags = gc.get_debug() if not wasOn: gc.set_debug(gc.DEBUG_SAVEALL) gc.collect() numGarbage = len(gc.garbage) del gc.garbage[:] if not wasOn: gc.set_debug(oldFlags) return numGarbage
def run(self): # do the garbage collection wasOn = gcDebugOn() oldFlags = gc.get_debug() if not wasOn: gc.set_debug(gc.DEBUG_SAVEALL) gc.collect() yield None # don't repr the garbage list if we don't have to if self.notify.getDebug(): self.notify.debug('gc.garbage == %s' % fastRepr(gc.garbage)) yield None self.garbage = list(gc.garbage) # don't repr the garbage list if we don't have to if self.notify.getDebug(): self.notify.debug('self.garbage == %s' % self.garbage) del gc.garbage[:] if not wasOn: gc.set_debug(oldFlags) self.numGarbage = len(self.garbage) yield None if self._args.verbose: self.notify.info('found %s garbage items' % self.numGarbage) self.referrersByReference = {} self.referrersByNumber = {} self.referentsByReference = {} self.referentsByNumber = {} self.cycles = [] self.cycleSets = [] self.cycleIds = set() # grab the referrers (pointing to garbage) if self._args.fullReport and (self.numGarbage != 0): if self._args.verbose: self.notify.info('getting referrers...') for i in xrange(self.numGarbage): yield None for result in self._getReferrers(self.garbage[i]): yield None byNum, byRef = result self.referrersByNumber[i] = byNum self.referrersByReference[i] = byRef # grab the referents (pointed to by garbage) if self.numGarbage > 0: if self._args.verbose: self.notify.info('getting referents...') for i in xrange(self.numGarbage): yield None for result in self._getReferents(self.garbage[i]): yield None byNum, byRef = result self.referentsByNumber[i] = byNum self.referentsByReference[i] = byRef # find the cycles if self._args.findCycles and self.numGarbage > 0: if self._args.verbose: self.notify.info('detecting cycles...') for i in xrange(self.numGarbage): yield None for newCycles in self._getCycles(i, self.cycleSets): yield None self.cycles.extend(newCycles) # if we're not doing a full report, add this cycle's IDs to the master set if not self._args.fullReport: for cycle in newCycles: yield None self.cycleIds.update(set(cycle)) if self._args.findCycles: s = ['===== GarbageReport: \'%s\' (%s items, %s cycles) =====' % ( self._args.name, self.numGarbage, len(self.cycles))] else: s = ['===== GarbageReport: \'%s\' (%s items) =====' % ( self._args.name, self.numGarbage)] if self.numGarbage > 0: # make a list of the ids we will actually be printing if self._args.fullReport: garbageIds = range(self.numGarbage) else: garbageIds = list(self.cycleIds) garbageIds.sort() numGarbage = len(garbageIds) # log each individual item with a number in front of it if not self._args.fullReport: abbrev = '(abbreviated) ' else: abbrev = '' s.append('===== Garbage Items %s=====' % abbrev) digits = 0 n = numGarbage while n > 0: yield None digits += 1 n /= 10 digits = digits format = '%0' + '%s' % digits + 'i:%s \t%s' for i in xrange(numGarbage): yield None id = garbageIds[i] objStr = safeRepr(self.garbage[id]) maxLen = 5000 if len(objStr) > maxLen: snip = '<SNIP>' objStr = '%s%s' % (objStr[:(maxLen-len(snip))], snip) s.append(format % (id, itype(self.garbage[id]), objStr)) if self._args.findCycles: s.append('===== Garbage Cycles =====') for i in xrange(len(self.cycles)): yield None s.append('%s' % self.cycles[i]) if self._args.fullReport: format = '%0' + '%s' % digits + 'i:%s' s.append('===== Referrers By Number (what is referring to garbage item?) =====') for i in xrange(numGarbage): yield None s.append(format % (i, self.referrersByNumber[i])) s.append('===== Referents By Number (what is garbage item referring to?) =====') for i in xrange(numGarbage): yield None s.append(format % (i, self.referentsByNumber[i])) s.append('===== Referrers (what is referring to garbage item?) =====') for i in xrange(numGarbage): yield None s.append(format % (i, self.referrersByReference[i])) s.append('===== Referents (what is garbage item referring to?) =====') for i in xrange(numGarbage): yield None s.append(format % (i, self.referentsByReference[i])) self._report = s if self._args.log: self.printingBegin() for i in xrange(len(self._report)): yield None self.notify.info(self._report[i]) self.printingEnd() yield Job.Done