I also hit this leak after upgrading from Zope-2.9.4 to Zope-2.11.1. The attachment contains a simple but working fix (I hope someone will create a more elegant solution).
Here is a sample PageTemplate that will trigger a memory leak:
<div tal:define="row python:context.some_Z_SQL_Method()[0]" tal:content="row/some_column"></div>
Someone willing to fix this bug will find this stack trace of evaluation of tal:content expression useful:
...
Module zope.tales.expressions, line 217, in __call__
Module Products.PageTemplates.Expressions, line 124, in _eval
Module zope.tales.expressions, line 124, in _eval
Module Products.PageTemplates.Expressions, line 79, in boboAwareZopeTraverse
Module zope.interface.declarations, line 375, in implementedByFallback
...
Another example that leaks memory:
from zope.traversing.interfaces import ITraversable
ITraversable(row, None) # row is an instance of Shared.DC.ZRDB.Results.r
ITraversable instance is created somwhere on the way of evaluating tal:content="row/some_column" expression. As a consequence the class Shared.DC.ZRDB.Results.r gets registered somewhere in ZOPE inteface machinery which prevents garbage collector from freeing it and other referenced objects (like Shared.DC.ZRDB.Results.SQLAlias objects).
Tracking references using gc.get_referrers() I found that zope.interface.adapter.AdapterLookup instance keeps cache that looks like this:
{
<InterfaceClass zope.traversing.interfaces.ITraversable>: {
<implementedBy Shared.DC.ZRDB.Results.r>: <class 'zope.traversing.adapters.DefaultTraversable'>,
<implementedBy Shared.DC.ZRDB.Results.r>: <class 'zope.traversing.adapters.DefaultTraversable'>,
<implementedBy Shared.DC.ZRDB.Results.r>: <class 'zope.traversing.adapters.DefaultTraversable'>,
...
},
...
}
On my production machine this bug leaks almost 2GB of memory daily. The fix for the class Shared.DC.ZRDB.Results.r is the most urgent, but other on-the-fly created classes are also affected.
I also hit this leak after upgrading from Zope-2.9.4 to Zope-2.11.1. The attachment contains a simple but working fix (I hope someone will create a more elegant solution).
Here is a sample PageTemplate that will trigger a memory leak: context. some_Z_ SQL_Method( )[0]" tal:content= "row/some_ column" ></div>
<div tal:define="row python:
Someone willing to fix this bug will find this stack trace of evaluation of tal:content expression useful: expressions, line 217, in __call__ PageTemplates. Expressions, line 124, in _eval expressions, line 124, in _eval PageTemplates. Expressions, line 79, in boboAwareZopeTr averse declarations, line 375, in implementedByFa llback
...
Module zope.tales.
Module Products.
Module zope.tales.
Module Products.
Module zope.interface.
...
Another example that leaks memory: .interfaces import ITraversable DC.ZRDB. Results. r
from zope.traversing
ITraversable(row, None) # row is an instance of Shared.
ITraversable instance is created somwhere on the way of evaluating tal:content= "row/some_ column" expression. As a consequence the class Shared. DC.ZRDB. Results. r gets registered somewhere in ZOPE inteface machinery which prevents garbage collector from freeing it and other referenced objects (like Shared. DC.ZRDB. Results. SQLAlias objects).
Tracking references using gc.get_referrers() I found that zope.interface. adapter. AdapterLookup instance keeps cache that looks like this: .interfaces. ITraversable> : { DC.ZRDB. Results. r>: <class 'zope.traversin g.adapters. DefaultTraversa ble'>, DC.ZRDB. Results. r>: <class 'zope.traversin g.adapters. DefaultTraversa ble'>, DC.ZRDB. Results. r>: <class 'zope.traversin g.adapters. DefaultTraversa ble'>,
{
<InterfaceClass zope.traversing
<implementedBy Shared.
<implementedBy Shared.
<implementedBy Shared.
...
},
...
}
On my production machine this bug leaks almost 2GB of memory daily. The fix for the class Shared. DC.ZRDB. Results. r is the most urgent, but other on-the-fly created classes are also affected.