[Buildbot-commits] [Buildbot] #2272: Eviction of BuildStatus objects

Buildbot nobody at buildbot.net
Tue Apr 3 19:53:06 UTC 2012


#2272: Eviction of BuildStatus objects
----------------------+-----------------------
Reporter:  szager     |      Owner:
    Type:  undecided  |     Status:  new
Priority:  major      |  Milestone:  undecided
 Version:  0.8.6p1    |   Keywords:
----------------------+-----------------------
 The memory usage of our buildbot master seems to grow linearly with time
 (which corresponds pretty well to number of builds).  There doesn't seem
 to be any limit to this behavior; if we don't restart the master for a
 long time, it will grow until the OS starts swapping, which effectively
 kills the master and forces a restart.  That happens when the master
 process is using >10GB on a 12GB system.

 I've done a bit of heap profiling on a running master, and it seems like
 there are *way* too many BuildStatus, BuildStepStatus, StepProgress, and
 LogFile objects in memory.

 I inspected all the live instances of
 buildbot.status.builder.BuilderStatus and looked at the buildCache fields.
 What I noticed is that for most builders,
 len(builder_status.buildCache.cache) is equal to the maximum allowed size
 of the cache, but len(builder_status.buildCache.weakrefs) is typically
 five times the maximum allowed size of the cache!

 So, I used the heap profiler to see where references to BuildStatus
 objects were being held.  From what I can tell, it seems like circular
 references between BuildStatus, BuildStepStatus, and LogFile (and maybe
 some other status-related objects) are the issue here.  Theoretically, the
 python garbage collector should be able to detect circular references
 between unreachable objects and clean them up; but it's not 100% efficient
 (for reasons of algorithmic complexity).

 First of all, I'd like to know whether this all sounds plausible.

 Secondly, I'd like to hear opinions on a proposed fix, which is to use
 weakrefs for all the parent pointers in status objects; e.g., in
 buildbot.status.buildstep.py:

 class BuildStepStatus(styles.Versioned):
   def __init__(self, parent, master, step_number):
     self.build = weakref.ref(parent)
     self.builder = parent.getBuilder()
     self.build_number = parent.getNumber()
     ...

   def getBuildStatus(self):
     result = self.build()
     if result is None:
       result = self.builder.getBuildByNumber(self.build_number)
       self.build = weakref.ref(result)
     return result

 And, obviously, all usage of stepstatus.build would need to be changed to
 stepstatus.getBuildStatus().

 Thoughts?

 Thanks,

 Stefan

-- 
Ticket URL: <http://trac.buildbot.net/ticket/2272>
Buildbot <http://buildbot.net/>
Buildbot: build/test automation


More information about the Commits mailing list