Edgewall Software

Ticket #6614: debug-mem-growth.diff

File debug-mem-growth.diff, 2.7 KB (added by cboos, 10 months ago)

same as explicit_gc.diff + some stats about accumulated objects

  • trac/web/main.py

     
    390390    finally: 
    391391        if env and not run_once: 
    392392            env.shutdown(threading._get_ident()) 
     393            # Now it's a good time to do some clean-ups 
     394            import gc 
     395            gc.disable() 
     396            gc.set_debug(gc.DEBUG_UNCOLLECTABLE) 
     397            unreachable = gc.collect() 
     398            env.log.info("%d unreachable objects found.", unreachable) 
     399            uncollectable = len(gc.garbage) 
     400            if uncollectable: 
     401                del gc.garbage[:] 
     402                env.log.warn("%d uncollectable objects found.", uncollectable) 
     403            print_gc_stats(env) 
    393404 
    394405def _dispatch_request(req, env, env_error): 
    395406    resp = [] 
     
    428439        if env: 
    429440            env.log.exception(e) 
    430441 
     442        raise e # DEBUG - short-circuit Trac error reporting 
     443 
    431444        exc_info = sys.exc_info() 
    432445        try: 
    433446            message = "%s: %s" % (e.__class__.__name__, to_unicode(e)) 
     
    557570        else: 
    558571            envs[env_name] = env_path 
    559572    return envs 
     573 
     574 
     575def print_gc_stats(env): 
     576    print '---------------- GC stats ----------------------' 
     577    import gc 
     578    live_objects = {} 
     579    for obj in gc.get_objects(): 
     580        live_objects[id(obj)] = type(obj) 
     581    print "live objects: ", len(live_objects) 
     582    first = True 
     583    if hasattr(env, '_accumulated'): 
     584        first = False 
     585        accumulated = env._accumulated 
     586        stats = env._stats 
     587        print "accumulated objects: ", len(accumulated) 
     588    else: 
     589        accumulated = env._accumulated = {} 
     590        stats = env._stats = {} 
     591    # retrieving previous stats 
     592    oldstats = {} 
     593    for t,cnt in stats.iteritems(): 
     594        oldstats[t] = [cnt[0]] 
     595    # analysing new stuff 
     596    for i,t in live_objects.iteritems(): 
     597        if i not in accumulated: 
     598            cnt = stats.setdefault(t, [0]) 
     599            cnt[0] += 1 
     600            accumulated[i] = t 
     601    if first: 
     602        return [] 
     603    # removing old stuff 
     604    delete = [] 
     605    for i,t in accumulated.iteritems(): 
     606        if i not in live_objects: 
     607            cnt = stats[t] 
     608            cnt[0] -= 1 
     609            delete.append(i) 
     610    for i in delete: 
     611        del accumulated[i] 
     612    print 'stats by type:' 
     613    for t in sorted(stats.keys(), key=lambda x: str(x)): 
     614        newval = stats[t] 
     615        oldval = oldstats.get(t) 
     616        if not oldval: 
     617            print t, 'delta:', newval 
     618        elif oldval[0] != newval[0]: 
     619            print t, 'total:', newval[0], 'delta:', newval[0] - oldval[0] 
     620    print '------------------------------------------------'