[ZODB-Dev] Memory out of control when *NOT* changing objects
Tim Peters
tim at zope.com
Tue Oct 12 15:44:33 EDT 2004
[Dieter Maurer]
> ...
> This is unfortunately a problem with the current ZODB release. Hopefully,
> it will get better with future ones:
>
> As you found out, your ZODB cache grows without limits.
>
> Usually, the ZODB connection performs a cache
> garbage collection at transaction boundaries.
> However, it can do this only, when it is informed about
> such boundaries.
>
> In the current ZODB (ZODB 3.2, at least), a ZODB connection
> is only informed about transaction boundaries when
> at least one of its objects registered with the transaction
> (because it was modified). If only reads are performed,
> the connection is not notified.
>
> This is a bug!
An exclamation point makes any statement preceding it true <wink>.
> For my MVCC implementation, a connection must learn about each
> transaction boundary whether or not one of its objects is modified.
> Therefore, I force the connection to register itself with the
> transaction. This way, it gets informed for every boundary.
>
> Hopefully, future ZODB connections will do something similar...
3.3 tries to be less persnickety, but it can be complicated. Here's part of
3.3's Connection docstring:
The logic for handling modifications assumes that the thread that
opened a Connection (called db.open()) is the thread that will use
the Connection. If this is not true, you should pass synch=False
to db.open(). When the synch option is disabled, some transaction
boundaries will be missed by the Connection; in particular, if a
transaction does not involve any modifications to objects loaded
from the Connection and synch is disabled, the Connection will
miss the transaction boundary. Two examples of this behavior are
db.undo() and read-only transactions.
The short course is that it should no longer be "a problem" for most uses,
but applications are still free to screw themselves, in multiple ways.
> You can work around this problem by calling "connection._incrgc()"
> yourself after a transaction boundary.
I think Connection.cacheGC() is preferred. I think that mostly because
names with underscores "should be" treated as private in Python. In this
specific case, I note that Connection._incrgc() doesn't even exist in ZODB
3.3, but Connection.cacheGC() (still) does.
More information about the ZODB-Dev
mailing list