Memory leak in Shared.DC.ZRDB.Results.SQLAlias
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
Products.ZSQLMethods |
Won't Fix
|
Medium
|
Unassigned |
Bug Description
A leak happens with objects of class Shared.
using traversal with a Z SQL Method.
1. Create a Z SQL Method named 'Sql' with one argument named 'my_arg':
SELECT my_column AS my_column_alias
FROM my_table
WHERE my_primary_key = '<dtml-var my_arg sql_quote>'
check 'Allow "simple" direct traversal' in Advanced.
2. Create a DTML Document named 'Leak':
<dtml-var my_column_alias>
Then each time calling http://<host>/Sql/1/Leak, one additional Instance of
Shared.
'my_column_alias' being referenced by it's attribute _n)
will be created but never again freed unless Zope is restarted.
Notes:
- We used a python 2.4.4 build with Py_TRACE_REFS switched on.
- Cyclic garbage collection is active, but gc.collect() does not free the
SQLAlias instances. (sys.getrefcount() says 4)
affects: | zope2 → products.zsqlmethods |
I can confirm that this leak is there, and has in fact caused
me to stop using the ZRDB.Results class altogether. Here is
where the problem arises:
- For each result set (i.e., each invocation of a SQL method),
the Results class creates a new class on-the-fly, named 'r'.
It creates an uppercase and lowercase alias for each column
in the result set's schema, and sets those aliases as
attributes of the 'r' class, in order to get their '__of__'
methods called when the alias is requested as an attribute
of an instance of 'r'.
- The cycle is thus betweeen the on-the-fly class, which
is stashed as the '_class' attribute of the Results instance,
and the alias(es). I don't know why that 'r' class is
unreachable for GC, but it seems to be so. I also don't
know how to write a test for the (non)existence of the
cycle.
My workaround was to move to using a results class which did
not attempt to DWIM the uppercase and lowercase aliases at
all: the columns can only be accessed using the same spelling
that was used in the original SQL. BBB will make this harder
to do in the ZRDB.Results module.