[Zope3-checkins] CVS: Zope3/src/zodb - connection.py:1.19 serialize.py:1.16
Jeremy Hylton
jeremy@zope.com
Mon, 17 Mar 2003 12:09:41 -0500
Update of /cvs-repository/Zope3/src/zodb
In directory cvs.zope.org:/tmp/cvs-serv30495/src/zodb
Modified Files:
connection.py serialize.py
Log Message:
Fix vast memory leak in object pickling.
There was a cycle between the ObjectWriter and its Pickler, which was
not collected because the Pickler does not participate in GC. Add a
close() method that releases references to the Pickler.
=== Zope3/src/zodb/connection.py 1.18 => 1.19 ===
--- Zope3/src/zodb/connection.py:1.18 Thu Mar 13 17:11:34 2003
+++ Zope3/src/zodb/connection.py Mon Mar 17 12:09:41 2003
@@ -454,6 +454,7 @@
writer = ObjectWriter(self)
for obj in writer.newObjects(object):
self._commit_store(writer, obj, transaction)
+ writer.close()
def _commit_store(self, writer, pobject, transaction):
oid = pobject._p_oid
=== Zope3/src/zodb/serialize.py 1.15 => 1.16 ===
--- Zope3/src/zodb/serialize.py:1.15 Thu Mar 13 16:32:27 2003
+++ Zope3/src/zodb/serialize.py Mon Mar 17 12:09:41 2003
@@ -96,6 +96,16 @@
_marker = object()
class ObjectWriter:
+ """Serializes objects for storage in the database.
+
+ The ObjectWriter creates object pickles in the ZODB format. It
+ also detects new persistent objects reachable from the current
+ object.
+
+ The client is responsible for calling the close() method to avoid
+ leaking memory. The ObjectWriter uses a Pickler internally, and
+ Pickler objects do not participate in garbage collection.
+ """
def __init__(self, jar=None):
self._file = StringIO()
@@ -105,6 +115,11 @@
if jar is not None:
assert hasattr(jar, "newObjectId")
self._jar = jar
+
+ def close(self):
+ # Explicitly break cycle involving pickler
+ self._p.persistent_id = None
+ self._p = None
def _persistent_id(self, obj):
"""Test if an object is persistent, returning an oid if it is.