Personal tools
You are here: Home Open Source Documents Avoiding memory leaks in Zope2 apps
Document Actions

Avoiding memory leaks in Zope2 apps

by Christian Heimes last modified 2004-10-06 21:41

DON'Ts list

  • Don't store wrapped objects in an attribute which is saved to ZODB. ZODB tries to handle them but it may screw up. Always remove the wrapper by calling aq_base(obj).

  • Try to avoid storing persistent objects in an attribute because it may result into objects reference cycles which WILL screw up the garbarage collection.

  • You can't use weakref to avoid reference cylcles with the old style ExtensionClass and ZODB <3.3. This means that weakrefs don't work with all Zope 2.7 and earlier objects because every persistent or acquisition capable is based on ExtensionClass.Base.

  • Never store persistent or an acquisition wrapped object at module level. It WILL screp up. You should avoid using module level vars because they aren't working across ZEO clients and they aren't thread safe unless you are using special care of the thread safty.

  • Don't store acquisition wrapped objects as REQUEST attributes. Putting them in "other" is okay as "other" is explicitly cleared when the request is complete. (Dieter Maurer)

  • Avoid creating a new SESSION container on every request. Note that even code like session = REQUEST.SESSION is creating a new session container if there is no session available for the current browser session. For users which aren't accepting the session cookie (and tools like apache benchmark, google bot ...) a new session container is created on each request! Instead you should use this syntax:

    session = context.session_data_manager.getSessionData(create=False)
    if session is not None:
        # has session
        # ...
    

Finding memory leaks

You can use the LeakFinder product http://zope.org/Members/hathawsh/LeakFinder from Shane Hathawsh. For newer version of Zope you have to alter LeakFinder:188 to c._cache = PickleCache(c, cache.cache_size)

Finding leaking sessions

If you can see an increasing count of Products.Transience.TransientObject.TransientObject that is increasing one object per request than you have probably a problem with your session usage. Simply add the prstack() function from my getCaller() howto to TransientObject.__init__ to see which methods are creating the sessions.


Powered by Plone CMS, the Open Source Content Management System