Simon Michael wrote:

> John Barratt wrote:
>
>> the problem (which seems likely) then you can ghostify the objects
>> that were ghosts to begin with, and it will save memory (unless all
>> those objects are already in cache).
>
>
> This is rather interesting, but I don't quite follow what's happening.
> If  you can say a little more, or suggest a doc reference, I'm all ears.

In general when an object is first loaded from the ZODB it is in a 'ghost' state, and is only a shell, it has no attributes etc. When you access (almost) any attribute on that object (eg. do : value = ob.attr), it gets activated (the contents are loaded automatically, and then the value returned). This is when the real memory usage takes place.

So if you get an object from the ZODB and don't access any attributes, it will remain in a ghosted state. Some core python attributes *don't* cause it to activate such as accessing __dict__, and also clearly the reserved persistent _p_* attributes.

If you look at the Cache Paramaters tab of your Database in the Control Panel (at least with Zope 2.6.2, perhaps 2.6.1) you can see how many objects are in memory, and how many are just 'ghosts'. I think ghosts are only 'removed' after a restart, and essentially just contain a _p_oid that references the object in the ZODB, ready for re-activation.

A general reference for the ZODB can be found here that explains more :

http://www.python.org/workshops/2000-01/proceedings/papers/fulton/zodb3.html

An example use (and good discussion) that is similar, can be found at the link below. I found this after having problems with objects not de-ghostifying properly when just accessing __dict__ :

http://aspn.activestate.com/ASPN/Mail/Message/zodb-dev/913762

Also a grep through the zope source code & some products will also find many examples of 'deactivating' objects after a 'walk' :

eg. From OFS.ObjectManager :
    def manage_afterAdd(self, item, container):
        for object in self.objectValues():
            try: s=object._p_changed
            except: s=0
            if hasattr(aq_base(object), 'manage_afterAdd'):
                object.manage_afterAdd(item, container)
            if s is None: object._p_deactivate()

A change to my example code that would be advisable is the wrapping of the _p_changed test in a try/except incase the object is None, or for some reason isn't persistent, and hence doesn't have a _p_changed.

I hope this helps & makes sense!

Cheers,

JB.



_______________________________________________
Zope-Dev maillist - [EMAIL PROTECTED]
http://mail.zope.org/mailman/listinfo/zope-dev
** No cross posts or HTML encoding! **
(Related lists - http://mail.zope.org/mailman/listinfo/zope-announce
http://mail.zope.org/mailman/listinfo/zope )

Reply via email to